【问题标题】:ddply 'drop=FALSE' equivalent in data.tabledata.table 中的 ddply 'drop=FALSE' 等效项
【发布时间】:2018-03-16 12:54:28
【问题描述】:

当使用ddply 像这样返回一个汇总数据的数据框时:

new_data <- ddply(data, .(grp1, grp2), function(x){
   val_list <- some_func(x.some_val)
   data.frame(
   val_1 = val_list[1],
   val_2 = val_list[2],
   val_3 = val_list[3]
   )}, .drop=FALSE
)

.drop=FALSE 表示我得到grp1grp2 组合的行,即使data 中不存在这些组合。

当使用dt[,.(val1=some_func(some_val1, some_val2)), by='grp1,grp2'] 制作汇总表时,我正在寻找data.table 中的等效功能,因为这将排除不存在的组合。

编辑:更完整的例子

输入:

data = read.csv(text = "
grp1, grp2, some_var1, some_var2
a, x, 3, 1
a, y, 3, 2
a, y, 3, 2
b, x, 3, 2
b, y, 4, 2
b, y, 4, 1 
c, x, 5, 1
c, y, 5, 2 
c, z, 5, 2")

现在假设我想要每个组的 (some_var1 * some_var2) 的平均值以及每个 var 的总和。

如果我使用 ddply:

library(plyr)
new_data <- ddply(data, .(grp1, grp2), function(x){
   data.frame(
   val_1 = mean(x$some_var1 * x$some_var2),
   val_2 = sum(x$some_var1),
   val_3 = sum(x$some_var2)
   )}, .drop=FALSE
)

输出:

grp1, grp2, val_1, val_2, val_3
a, x, 3, 3, 1
a, y, 6, 6, 4
a, z, NA, NA, NA
b, x, 6, 3, 2
b, y, 6, 8, 3
b, z, NA, NA, NA
c, x, 5, 5, 1
c, y, 10, 5, 2
c, z, 10, 5, 2

但使用data.table 时不会包含NA 行,因为原始数据没有grp1grp2 的组合。 显然,这是一个大大简化的示例,实际上我正在计算更多可能的组,使用三个分组变量,并返回三个以上的新简单汇总变量。

【问题讨论】:

  • 我认为提供一个示例数据框和您想要的输出会很有用
  • @KenS。添加了更多示例

标签: r data.table


【解决方案1】:

我认为您提到的ddply 方法实际上可能是您最好的选择。我想出了另一个解决方案,但老实说,我更喜欢ddply..

我们开始吧:

f <- function(x, y) {list( mean(x * y), sum(x), sum(y))}

dt[, c("v1", "v2", "v3") := f(some_var1, some_var2), by = list(grp1, grp2)]
dt[, c("some_var1", "some_var2") := NULL]

现在,我们将通过使用merge() 进行左连接来模仿.drop=FALSE 功能。这里的诀窍是,我们使用grid::expand.grid 构造了一个左表,其中包含grp1grp2 的所有组合:

left_tab <- grid::expand.grid(grp1 = unique(dt$grp1), grp2 = unique(dt$grp2))
merge(left_tab, unique(dt), all.x = TRUE)
#       grp1 grp2 val_1 val_2 val_3
# 1    a    x     3     3     1
# 2    a    y     6     6     4
# 3    a    z    NA    NA    NA
# 4    b    x     6     3     2
# 5    b    y     6     8     3
# 6    b    z    NA    NA    NA
# 7    c    x     5     5     1
# 8    c    y    10     5     2
# 9    c    z    10     5     2

【讨论】:

  • 嗯,是的,这似乎比ddply 更复杂,特别是因为我的f 函数实际上必须返回更复杂的计算。我真的希望通过使用data.table 来提高速度,但我想我会在短期内坚持使用ddply,并可能在未来某个时候对您提出的解决方法进行基准测试。
猜你喜欢
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-23
  • 2013-11-03
  • 1970-01-01
  • 2014-04-26
相关资源
最近更新 更多