使用R中的循环有效地绘制子列表参数

时间:2013-12-31 06:48:39

标签: r list loops lapply sublist

我无法制作循环,我不知道出了什么问题。我的数据包含列表中的列表。我有> 50个主要列表,即[[i]]。每个[[i]]包含20`i``(=子列表)。我的数据的子集看起来像

>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

... ...

当我想在一个图中绘制具有不同颜色的每个子列表时,它不起作用

#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))

我收到没有任何情节的警告

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
... ...

当我绘制没有任何x- / y-限制时,它没有给出任何警告或绘图,只是在工作空间中显示NULL!

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

然而,当我逐个绘制数据时,它可以工作,但这是处理如此大的数据集的一种不切实际的方法

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')

知道为什么这个简单的循环不起作用?

1 个答案:

答案 0 :(得分:1)

@ SimonO10突出了你的代码中的问题,但除此之外,你考虑过ggplot吗?它真的很容易做到这种类型的东西。您将遇到的主要问题是您需要将数据转换为长格式。但是一旦你完成了这项计划,情节几乎是微不足道的:

# 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()

grouped scatter plot

facet_wrap如果你想让东西出现在不同的图表中(注意数据改变了b / c我没有设置随机种子):

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)

facetted by sub.id

为了让你的数据变成长格式,我开始在你的结构中提供一些数据(见帖子的结尾我是怎么做的):

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
# ...

然后转换为长格式@baptiste建议(注意数字不完全匹配b / c我重新生成随机数据)

# 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
# ...           

和生成数据的代码:

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 } )