使用R中的循环高效地绘制子列表参数
我很难做一个循环,我不知道出了什么问题。我的数据包含列表中的列表。我有超过50个主要列表,即[I]]。每个[[i]]包含20个'i`(=子列表)。我的数据的一个子集看起来像使用R中的循环高效地绘制子列表参数,r,list,loops,lapply,sublist,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 263
>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')
你知道为什么这个简单循环不起作用吗?@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()
使用facet\u wrap
如果您想在不同的图形中显示内容(注意数据已更改b/c我没有设置随机种子):
为了将您的数据转换为长格式,我从您的结构中的一些数据开始(我是如何做到的,请参阅本文末尾):
然后转换为@baptiste建议的长格式(注意数字与b/c I重新生成的随机数据不完全匹配)
#转换为长格式
图书馆(E2)
数据这可能是为数不多的几个地方之一,因为for
循环在R中是有意义的,我会尝试一下。你期望的是,通过设计工作,某些东西不会工作<代码>$
从不计算它的参数。有关详细信息,请使用[,i]
而不是$
重塑2::melt(数据)
将您的数据转换为长格式的data.frame,非常适合于ggplot2或lattice。任何使用base R解决此类问题的方法?@baptiste,好主意,没有意识到melt
可以使用嵌套列表。您确实需要这样做:melt(数据,id.vars=c(“高度”、“重量”))
。我将在下面更新我的代码。谢谢,但您绘制了所有内容(1-1、1-2、2-1、2-2等)。你怎么只画1-1和1-2?很抱歉,我不熟悉ggplot。只是子集数据。不要将数据
传递给ggplot,而是传递子集(数据,id==1)
。感谢您的更新。好。。。也许我要求的太多了,但是如何为id=L1的每个子集创建一个循环??正如我所说的,有50多个ID,即循环将创建>50个绘图…如果您希望它们同时显示,可以使用facet\u wrap()
,但如果您想要50个图形,这可能太多了。否则,您可以将ggplot
语句放入for循环中,并将循环索引值传递给子集
表达式。我将添加一个facet\u wrap示例。
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)
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
# ...
# 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 } )