【问题标题】:How to apply aggregation and rbind on list of data.table?如何在 data.table 列表上应用聚合和 rbind?
【发布时间】:2021-05-08 17:09:35
【问题描述】:

我尝试将此表示应用于许多 data.table 的列表,并根据许多标准进行聚合。 我尝试了一些 lapply、mapply、for、...的组合,但没有成功。

我的输入数据是这个 data.table 列表:

nb.row <- 50
nb.col <- 5
lst.DT <- replicate(5, as.data.table(matrix(runif(n=nb.row*nb.col, min = 0, max = 100), nb.row, nb.col)), simplify = FALSE)
crit <- as.data.table(replicate(3,sample(1:5,nb.row, replace = TRUE)))
names(crit) <- c("C1", "C2", "C3")
lst.DT <- lapply(lst.DT, cbind, crit)

我试图总结的代码,以简化:

dt1.1 <- lst.DT[[1]][, .(new = sum(V4 / V5)), by = C1]
dt1.2 <- lst.DT[[1]][, .(new = sum(V4 / V5)), by = C2]
dt1.3 <- lst.DT[[1]][, .(new = sum(V4 / V5)), by = C3]

dt2.1 <- lst.DT[[2]][, .(new = sum(V4 / V5)), by = C1]
dt2.2 <- lst.DT[[2]][, .(new = sum(V4 / V5)), by = C2]
dt2.3 <- lst.DT[[2]][, .(new = sum(V4 / V5)), by = C3]

...

dtX.1 <- lst.DT[[X]][, .(new = sum(V4 / V5)), by = C1]
dtX.2 <- lst.DT[[X]][, .(new = sum(V4 / V5)), by = C2]
dtX.3 <- lst.DT[[X]][, .(new = sum(V4 / V5)), by = C3]

res1 <- rbindlist(list(dt1.1, dt1.2, dt1.3))
res2 <- rbindlist(list(dt2.1, dt2.2, dt2.3))
...
resX <- rbindlist(list(dtX.1, dtX.2, dtX.3))

最终返回一个与 lst.DT 具有相同维度的列表,包含 res1、res2、...

如何执行这种事情? 非常感谢。

【问题讨论】:

  • 我跑了 rbindlist(list(dt1, dt2, dt3)) 这是它的工作..你不能得到“rbindlist”吗?
  • 哦,是的,我的 reprex 运行良好。我想做的是优化写作。示意地,遍历我的 data.table 列表,然后遍历条件(C1、C2、C3),使用 lapply 等...
  • 还是有点不清楚。输入数据是什么,要替换哪些步骤?
  • 对不起。我编辑了我的主要帖子。谢谢。

标签: r for-loop data.table lapply


【解决方案1】:

这里我针对这个问题给出另一种分析观点。总之,我重点关注不同列名C1,C2,C3相关的列表结构,然后rbind所有列表。

library(data.table)
sumby <- function(list_in,col_name){
    lapply(list_in, function(x) x[,.(new = sum(V4/V5)), by = col_name])
}

lt1 <- sumby(lst.DT,"C1")
lt2 <- sumby(lst.DT,"C2")
lt3 <- sumby(lst.DT,"C3")

# unify df's name in list then rbind all list
lt2 <- lapply(lt2, function(x) x[,.(C1=C2,new)])
lt3 <- lapply(lt3, function(x) x[,.(C1=C3,new)])
resu1 <- mapply(rbind,lt1,lt2,lt3, SIMPLIFY=FALSE)

【讨论】:

  • 谢谢,我会检查一下。
【解决方案2】:

一个例子:

res1a <- rbindlist(
  lapply(
    paste0('C', 1:3),
    function(Ci) lst.DT[[1]][, .(new = sum(V4 / V5)), by = Ci]
  ), 
  use.names = FALSE
)

另一个使用groupingsets()

vars <-  paste0('C', 1:3)
res1b <- groupingsets(
  lst.DT[[1]], j = sum(V4 / V5), by = vars, sets = as.list(vars)
)[, .(C1 = fcoalesce(.SD), new = V1), .SDcols = vars]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多