使用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
表示我获得grp1
和grp2
组合的行,即使data
中没有这些组合。
在使用data.table
制作汇总表时,我正在寻找dt[,.(val1=some_func(some_val1, some_val2)), by='grp1,grp2']
中的等效功能,因为这将排除不存在的组合。
编辑:更完整的示例
输入:
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
行不会被包含在内,因为原始数据没有grp1
和grp2
的组合。
显然这是一个大规模简化的例子,实际上我使用三个分组变量在更多可能的组中计算它,并返回三个以上的新简单摘要变量。
答案 0 :(得分: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]
现在,我们将使用.drop=FALSE
通过左连接来模仿merge()
- 功能。这里的诀窍是,我们使用grid::expand.grid
构建一个左表,其中包含grp1
和grp2
的所有组合:
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