在 R 中的循环中构建列表 - 使项目名称正确
Posted
技术标签:
【中文标题】在 R 中的循环中构建列表 - 使项目名称正确【英文标题】:Building a list in a loop in R - getting item names correct 【发布时间】:2012-09-12 18:16:53 【问题描述】:我有一个函数,它包含两个列表的循环并建立一些计算数据。我想将这些数据作为列表的列表返回,并按某个值进行索引,但我的赋值有误。
我正在尝试做的一个最小的例子是:
mybiglist <- list()
for(i in 1:5)
a <- runif(10)
b <- rnorm(16)
c <- rbinom(8, 5, i/10)
name <- paste('item:',i,sep='')
tmp <- list(uniform=a, normal=b, binomial=c)
mybiglist[[name]] <- append(mybiglist, tmp)
如果您运行此程序并查看输出 mybiglist,您会发现每个项目的命名方式出现了严重错误。
关于如何实现我真正想要的任何想法?
谢谢
ps。我知道在 R 中,如果不得不求助于循环,就会失败,但在这种情况下,我确实觉得有道理;-)
【问题讨论】:
c
不是一个好名字对象!!
【参考方案1】:
如果你不使用append
命令也可以:
mybiglist <- list()
for(i in 1:5)
a <- runif(10)
b <- rnorm(16)
c <- rbinom(8, 5, i/10)
name <- paste('item:',i,sep='')
tmp <- list(uniform=a, normal=b, binomial=c)
mybiglist[[name]] <- tmp
# List of 5
# $ item:1:List of 3
# ..$ uniform : num [1:10] 0.737 0.987 0.577 0.814 0.452 ...
# ..$ normal : num [1:16] -0.403 -0.104 2.147 0.32 1.713 ...
# ..$ binomial: num [1:8] 0 0 0 0 1 0 0 1
# $ item:2:List of 3
# ..$ uniform : num [1:10] 0.61 0.62 0.49 0.217 0.862 ...
# ..$ normal : num [1:16] 0.945 -0.154 -0.5 -0.729 -0.547 ...
# ..$ binomial: num [1:8] 1 2 2 0 2 1 0 2
# $ item:3:List of 3
# ..$ uniform : num [1:10] 0.66 0.094 0.432 0.634 0.949 ...
# ..$ normal : num [1:16] -0.607 0.274 -1.455 0.828 -0.73 ...
# ..$ binomial: num [1:8] 2 2 3 1 1 1 2 0
# $ item:4:List of 3
# ..$ uniform : num [1:10] 0.455 0.442 0.149 0.745 0.24 ...
# ..$ normal : num [1:16] 0.0994 -0.5332 -0.8131 -1.1847 -0.8032 ...
# ..$ binomial: num [1:8] 2 3 1 1 2 2 2 1
# $ item:5:List of 3
# ..$ uniform : num [1:10] 0.816 0.279 0.583 0.179 0.321 ...
# ..$ normal : num [1:16] -0.036 1.137 0.178 0.29 1.266 ...
# ..$ binomial: num [1:8] 3 4 3 4 4 2 2 3
【讨论】:
你能解释一下为什么mybiglist[[name]] <- tmp
中的“name”在双括号中吗?
@spops 双括号用于访问列表元素。单括号返回列表。
这就是append
与[[<element>]]
一起使用时失败的原因吗?因为你不能追加到元素,但你可以追加到列表? (我一直在琢磨将项目添加到列表的所有方法,并遇到了这篇文章,并且一直想知道)
@spops append
失败,因为整个列表用于替换其中一个元素。
@SvenHohenstein - 谢谢你的回答。有没有办法找到两个mybiglist
(mybiglist_A
和mybiglist_B
)之间的百分比差异?我可以使用identical()
来获取mybiglist_A
是否与mybiglist_B
完全相同,但想知道是否可以找到百分比差异?【参考方案2】:
改变
mybiglist[[name]] <- append(mybiglist, tmp)
到
mybiglist[[name]] <- tmp
【讨论】:
【参考方案3】:表明不需要显式的 for 循环
unif_norm <- replicate(5, list(uniform = runif(10),
normal = rnorm(16)), simplify=F)
binomials <- lapply(seq_len(5)/10, function(prob)
list(binomial = rbinom(n = 5 ,size = 8, prob = prob)))
biglist <- setNames(mapply(c, unif_norm, binomials, SIMPLIFY = F),
paste0('item:',seq_along(unif_norm)))
一般来说,如果您沿着for
循环路径,最好事先预先分配列表。这样内存效率更高。
mybiglist <- vector('list', 5)
names(mybiglist) <- paste0('item:', seq_along(mybiglist))
for(i in seq_along(mybiglist))
a <- runif(10)
b <- rnorm(16)
c <- rbinom(8, 5, i/10)
tmp <- list(uniform=a, normal=b, binomial=c)
mybiglist[[i]] <- tmp
【讨论】:
谢谢...虽然我不想实际创建均匀分布、正态分布和二项分布的列表 ;-) 这是我所追求的命名约定。 至少记得预分配!以上是关于在 R 中的循环中构建列表 - 使项目名称正确的主要内容,如果未能解决你的问题,请参考以下文章