列表优于编号的data.tables的优势

时间:2019-07-15 12:58:42

标签: r list assign

我有两个嵌套的for循环,在每个循环中我加载(在此处模拟)和操纵数据以创建多个列表。

library(data.table)
for(i in 1:20){
    perm <- rnorm(1); res <- list()
    for(j in 1:500){
        temp <- runif(5,0,20)
        res[[j]] <- data.table(a=temp/perm, b=temp+perm)
    }
    assign(paste0("x",i),res); rm(res)
}

因为内部for循环输出data.table,所以我在外部for循环的每次迭代中创建一个列表,以保存内部循环产生的不同data.tables。

我已经读过herehere,发现使用assign(.)的设置不是非常Rly,我想知道是否可以改进。

一方面,我喜欢对j循环的列表进行编号,这样我就可以将它们与加载到此处的数据集相关联(此处为模拟)。另一方面,i循环可以产生一个列表列表,但是我想知道除可伸缩性之外还有什么好处。

2 个答案:

答案 0 :(得分:3)

列表列表非常好并且易​​于使用。但是,模式“列表”的矩阵可以是非常方便的替代方法:

m <- 2
n <- 3
res <- vector(length = m * n, mode = "list")
res <- matrix(res, ncol = m)

library(data.table)
for(i in 1:n){
  perm <- rnorm(100)
  for(j in 1:m){
    temp <- runif(5,0,20)
    res[i,j] <- list(data.table(a=temp/perm[i], b=temp+perm[i]))
  }
}

res[1,] #result from first iteration of outer loop
#[[1]]
#            a         b
#1:  -6.434118  7.744621
#2:  -7.741497  9.607878
#3:  -3.200882  3.136663
#4:  -8.283567 10.380427
#5: -10.989466 14.236833
#
#[[2]]
#            a         b
#1: -12.045692 15.742150
#2: -13.199384 17.386375
#3:  -6.176316  7.377206
#4: -13.549293 17.885059
#5:  -3.025583  2.886829

答案 1 :(得分:1)

使用基本的R *pply*系列函数或map_*中的purrr系列函数对您都非常有益。这是使用基数R的代码:

res <- lapply(1:20, function(i) {
  perm <- rnorm(100)
  ret <- lapply(1:500, function(j) {
         temp <- runif(5, 0, 20)
         data.frame(a=temp/perm[i], b=temp+perm[i])
      })
})

优点:无需填充当前环境,您只有一个对象(res),可以轻松地使用循环和更多对象进行操作。将结果存储在列表中最直接的好处就是便捷。您可以一次性保存所有结果(save(res, file="res.rda"),计算有多少(length(res)),然后用lapplymap浏览所有结果。

说,您想从20个副本中的每个副本中获取第一个j索引:

j1 <- map(res, ~ .[[1]])

哦,您想要在一个数据帧中全部完成吗?

j1 <- map_dfr(res, ~ .[[1]])

第二个优点:您立即看到代码已损坏。对于每个i,您都会生成100个随机数(perm),但是您只使用过一个...每个i都有一个! (perm[i],代表1..20中的i)。为什么根本需要100个?