Reputation: 1378
I'm having trouble to make a loop and I have no idea what is going wrong. My data contains list within a list. I have >50 primary list i.e. [[i]]. Each of the [[i]] contains 20 `i`` (=sublist). A subset of my data looks like
>data
[[1]]$`1`
X Y Height_m kt_Result
1 253641.0 2630050 90 560
74 253845.7 2630552 90 270
156 254353.6 2630195 130 0
171 254554.9 2630220 170 390
173 254565.9 2630323 120 304
[[1]]$`2`
X Y Height_m kt_Result
5 253641.0 2630050 50 860
77 253845.7 2630552 20 370
159 254353.6 2630195 190 20
177 254554.9 2630220 140 310
200 254565.9 2630323 100 804
... ...
[[2]]$`1`
X Y Height_m kt_Result
4 253641.0 2630050 10 960
78 253845.7 2630552 20 220
150 254353.6 2630195 330 5
377 254554.9 2630220 670 340
100 254565.9 2630323 220 314
... ...
When I want to plot each of the sublist with different colors in one plot, it doesn't work
#blank plot (dfs is a different data frame with the same data)
plot(dfs[[1]]$kt_Result, dfs[[1]]$Height_m, type='n')
#plot sublist
lapply(1:length(data[[1]]), function(i)
points(data[[1]]$`i`$kt_Result, data[[1]]$`i`$Height_m,
ylim=rev(c(0, max(data[[1]]$`i`$Height_m))),
xlim= c(min(data[[1]]$`i`$kt_Result, na.rm=TRUE),
max(data[[1]]$`i`$kt_Result, na.rm=TRUE)), lwd=2, type='b',col=i))
I get warnings without any plot
There were 50 or more warnings (use warnings() to see the first 50)
> warnings()
Warning messages:
1: In max(data[[1]]$i$Height_m) : no non-missing arguments to max; returning -Inf
2: In min(data[[1]]$i$kt_Result, na.rm = TRUE) :
no non-missing arguments to min; returning Inf
3: In max(data[[1]]$i$kt_Result, na.rm = TRUE) :
no non-missing arguments to max; returning -Inf
... ...
When I plot without any x-/y- limits, it gives no warning or plot, just shows NULL in workspace!
lapply(1:length(data[[1]]), function(i)
points(data[[1]]$`i`$kt_Result, data[[1]]$`i`$Height_m,
lwd=2, type='p',col=i))
[[1]]
NULL
[[2]]
NULL
...
[[20]]
NULL
However, when I plot the data one by one, it works, but this is an impractical way to deal with such a large dataset
plot(dfs[[1]]$kt_Result, dfs[[1]]$Height_m, type='n')
points(data[[1]]$`1`$kt_Result, data[[1]]$`1`$Height_m, col='red')
points(data[[1]]$`2`$kt_Result, data[[1]]$`2`$Height_m, col='green')
... ...
points(data[[1]]$`19`$kt_Result, data[[1]]$`19`$Height_m, col='cyan')
points(data[[1]]$`20`$kt_Result, data[[1]]$`20`$Height_m, col='blue')
Any idea why this simple loop is not working?
Upvotes: 0
Views: 241
Reputation: 52677
@SimonO10 highlights the problem in your code, but beyond that, have you considered ggplot? It's really designed to do this type of stuff easily. The main problem you'll run into is you need to convert your data to long format. But once you've done that the plotting is almost trivial:
# Use ggplot to plot
ggplot(
subset(data, L1==1), # just use `data` here if you want all plots
aes(x=height, y=weight, color=paste(L1, L2, sep="-"))
) + geom_point() + scale_color_discrete(name="id-sub.id") + scale_y_reverse()
with facet_wrap
if you want stuff to show up in different graphs (note the data changed b/c I didn't set the random seed):
ggplot(
subset(data, L1==1), # just use `data` here if you want all plots
aes(x=height, y=weight, color=paste(L1, L2, sep="-"))
) + geom_point() + scale_color_discrete(name="id-sub.id") +
facet_wrap( ~ L2)
In order to get your data into long format, I started with some data in your structure (see end of post for how I did it):
data
# [[1]]
# [[1]]$`1`
# height weight
# 1 0.79199970 0.19434040
# 2 0.83137244 0.41325506
# ...
#
# [[1]]$`2`
# height weight
# 1 0.099096870 0.64563244
# 2 0.736456033 0.06103266
# ...
#
# [[2]]
# [[2]]$`1`
# height weight
# 1 0.2622071 0.176313366
# 2 0.5747873 0.887846513
# ...
then converted to long format as @baptiste suggested (note numbers don't match exactly b/c I regenerated random data)
# Convert to long format
library(reshape2)
data <- melt(data, id.vars=c("height", "weight"))
# height weight L2 L1
# 1 0.55637070 0.50990818 1 1
# 2 0.59839293 0.91242349 1 1
# ...
# 11 0.39170638 0.86185414 2 1
# 12 0.69356092 0.03145715 2 1
# ...
# 21 0.67580737 0.55668117 1 2
# 22 0.01335459 0.29615540 1 2
# ...
and the code to generate data:
data <-
replicate(5, simplify=F,
replicate(2, simplify=F,
data.frame(height=runif(10), weight=runif(10))
) )
data <- lapply( data, function(x) { names(x) <- seq_along(x); x } )
Upvotes: 1