【问题标题】:Using data.table function in lapply on a list with data.frames elements (Answer = setDT)在具有 data.frames 元素的列表上使用 lapply 中的 data.table 函数(答案 = setDT)
【发布时间】:2017-06-25 02:18:44
【问题描述】:

第一个问题,如果需要更多信息或背景,请告诉我。

这里和其他地方的许多答案都涉及在 data.table 函数中调用 lapply 。我想做相反的事情,这在纸上应该很容易lapply(list.of.dfs, fun(x) x) 但我不能让它与 data.table 函数一起使用。

我有一个列表,其中包含多个具有相同列但行数不同的 data.frames。这来自几个模拟场景的输出,因此它们必须单独处理,而不是 rbind'ed。

 #sample list of data.frames
  scenarios <- replicate(5, data.frame(a=sample(letters[1:4],10,T),
                              b=sample(1:2,10,T),
                              x=sample(1:10, 10), 
                              y =runif(10)), simplify = FALSE)

我想为每个元素添加一列,即 a 和 b 的 x/y 之和。
从示例部分的 data.table 文档中,为一个 data.frame 执行此操作的过程如下(搜索:在文档页面中按组引用添加新列):

test <- as.data.table(scenarios[[1]]) #must specify data.table class
test[, newcol := sum(x/y), by = .(a , b)][]

我想使用 lapply 对场景列表中的每个元素执行相同的操作并返回列表。 我最近的尝试:

lapply(scenarios, function(i) {as.data.table(i[, z := sum(x/y), by=.(a,b)]); i})

但我不断收到错误unused argument (by = .a,b))

在倾注了这个网站和其他网站的结果后,我一直无法解决这个问题。我相当确定这意味着我对调用匿名函数和/或使用 data.table 函数有些不理解。这是您使用 [ 作为函数的情况之一吗?或者可能我的 as.data.table 不合适。

This answer 是朝着正确方向迈出的一步(我认为),它涵盖了 fun(x) {... ; x} 使用匿名函数并返回 x。

谢谢!

【问题讨论】:

    标签: r data.table lapply


    【解决方案1】:

    您可以在此处改用setDT

    scenarios <- lapply(scenarios, function(i) setDT(i)[, z := sum(x/y), by=.(a,b)])
    
    scenarios[[1]]
       a b  x          y         z
     1: c 2  2 0.87002174  2.298793
     2: b 2 10 0.19720775 78.611837
     3: b 2  8 0.47041670 78.611837
     4: b 2  4 0.36705023 78.611837
     5: a 1  5 0.78922686 12.774035
     6: a 1  6 0.93186209 12.774035
     7: b 1  3 0.83118438  3.609307
     8: c 1  1 0.08248658 30.047494
     9: c 1  7 0.89382050 30.047494
    10: c 1  9 0.89172831 30.047494
    

    使用as.data.table,语法为

    scenarios <- lapply(scenarios, function(i) {i <- as.data.table(i); i[, z := sum(x/y),
                                                                         by=.(a,b)]})
    

    但不建议这样做,因为它会创建一个额外的副本,setDT 可以避免这种情况。

    【讨论】:

    • 非常感谢!我知道必须有一个工具来做到这一点。 +1
    • 感谢@Frank 的澄清。分号只是“这样做并传递给下一个”吗?
    • @JGiancarlo 分号只是“做这个;然后做另一个事情”——据我所知,这与将每个命令写在单独的行上完全相同。
    猜你喜欢
    • 2021-12-10
    • 2020-05-03
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多