【问题标题】:Assign values in a for loop using R使用 R 在 for 循环中赋值
【发布时间】:2017-04-20 15:04:54
【问题描述】:

全部:

当我尝试使用for 循环创建 5 个数据帧并将这五个数据帧分配给一个列表时,问题就来了。请看一个例​​子:

library(data.table)
set.seed(123)    
df <- as.data.table(list(rnorm(10,1,1), rnorm(10,1,1)))
list <- list() 
for(i in 2011:2015){
             list[[paste0("A_",i)]] <- df[, year := as.numeric(i)]
             }

所以,正如我所料,year 变量的值应该与每个元素中的i 相同。例如,list[1]year 的值应该是 2011。但是,上面的代码在所有元素中为 year 返回 2015:

    > list[1]
$A_2011
            V1         V2 year
 1:  0.4395244  2.2240818 2015
 2:  0.7698225  1.3598138 2015
 3:  2.5587083  1.4007715 2015
 4:  1.0705084  1.1106827 2015
 5:  1.1292877  0.4441589 2015
 6:  2.7150650  2.7869131 2015
 7:  1.4609162  1.4978505 2015
 8: -0.2650612 -0.9666172 2015
 9:  0.3131471  1.7013559 2015
10:  0.5543380  0.5272086 2015

我无法弄清楚我的代码有什么问题。如果有人能在这里指出问题,我将不胜感激。我想看看使用lapply 左右的任何其他解决方案,如果有的话。非常感谢!

【问题讨论】:

  • 快速修复:在您的循环中添加list[[paste0("A_",i)]]$year &lt;- i
  • 一般来说,把它放在一张桌子上会少很多痛苦,比如yrs = 2011:2015; res &lt;- df[rep(1:.N, length(yrs))][, year := rep(yrs, each = nrow(df))][]df[, rbindlist(Map(cbind, .(.SD), year = yrs))]
  • @Majo 修复有效!但是,我真的很想知道为什么我的代码不能按预期工作。我认为那里的逻辑是正确的。
  • @Frank 谢谢!多么美妙的解决方案!

标签: r for-loop data.table


【解决方案1】:
for(i in 2011:2015){
  list[[paste0("A_",i)]] <- df[, year := as.numeric(i)]
} 

如果有人能在这里指出问题,我将不胜感激。

&lt;- 生成指向同一个 data.table 的指针,df,而不是复制。将其包装在 copy() 中应该可以解决这个问题。但是,使用单个大表会更干净:

yrs = 2011:2015
res <- df[, rbindlist(Map(cbind, .(.SD), year = yrs))]

这有几个优点:

  • data.tables 列表遇到了奇怪的指针问题。
  • 大 data.table 允许使用 by= 迭代子表,这可以提高效率。

【讨论】:

  • 够清楚了!谢谢@Frank
【解决方案2】:

这行得通: 与上面相反,使用 dplyr 追加新列:

setNames(lapply(2011:2015, function(i){
    as.data.table(list(rnorm(10,1,1), rnorm(10,1,1))) %>% 
        mutate(year = i)
}), sprintf("A_%s", 2011:2015))

编辑种子处理:

setNames(lapply(2011:2015, function(i){
    set.seed(123)
    as.data.table(list(rnorm(10,1,1), rnorm(10,1,1))) %>% 
        mutate(year = i)
}), sprintf("A_%s", 2011:2015))

输出:

List of 5
 $ A_2011:'data.frame': 10 obs. of  3 variables:
  ..$ V1  : num [1:10] 0.44 0.77 2.56 1.07 1.13 ...
  ..$ V2  : num [1:10] 2.224 1.36 1.401 1.111 0.444 ...
  ..$ year: int [1:10] 2011 2011 2011 2011 2011 2011 2011 2011 2011 2011
 $ A_2012:'data.frame': 10 obs. of  3 variables:
  ..$ V1  : num [1:10] 0.44 0.77 2.56 1.07 1.13 ...
  ..$ V2  : num [1:10] 2.224 1.36 1.401 1.111 0.444 ...
  ..$ year: int [1:10] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012
 $ A_2013:'data.frame': 10 obs. of  3 variables:
  ..$ V1  : num [1:10] 0.44 0.77 2.56 1.07 1.13 ...
  ..$ V2  : num [1:10] 2.224 1.36 1.401 1.111 0.444 ...
  ..$ year: int [1:10] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
 $ A_2014:'data.frame': 10 obs. of  3 variables:
  ..$ V1  : num [1:10] 0.44 0.77 2.56 1.07 1.13 ...
  ..$ V2  : num [1:10] 2.224 1.36 1.401 1.111 0.444 ...
  ..$ year: int [1:10] 2014 2014 2014 2014 2014 2014 2014 2014 2014 2014
 $ A_2015:'data.frame': 10 obs. of  3 variables:
  ..$ V1  : num [1:10] 0.44 0.77 2.56 1.07 1.13 ...
  ..$ V2  : num [1:10] 2.224 1.36 1.401 1.111 0.444 ...
  ..$ year: int [1:10] 2015 2015 2015 2015 2015 2015 2015 2015 2015 2015

【讨论】:

  • 谢谢!使用 dplyr 绝对是另一个好方法。但是你知道为什么我的代码没有按预期工作吗?
  • 遗憾的是,我并不像我想用 data.table 更清楚地解释那样精通
猜你喜欢
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 2017-10-20
  • 2021-11-27
  • 1970-01-01
  • 2016-09-24
  • 2016-01-17
  • 2021-01-20
相关资源
最近更新 更多