简洁的data.table 解决方案已经posted 使用列numbers 而不是列names。这被认为是不好的做法
Frequently Asked Questions about data.table, section 1.1:
如果您的同事稍后出现并阅读您的代码,他们可能不得不四处寻找哪一列是第 5 列。如果您或他们在您的 R 程序中更改了更高的列顺序,您可能会产生错误的结果,而没有如果您忘记更改代码中引用第 5 列的所有位置,则会出现警告或错误。
所以,我想提出使用列名的替代方法。
变体 1
library(data.table)
setDT(df)[, .(average.Age = mean(Age),
average.Wages = mean(Wages),
sum.Education.University = sum(Education.University),
average.Productivity = mean(Productivity)),
by = Company]
Company average.Age average.Wages sum.Education.University average.Productivity
1: A 27.00000 56666.67 2 102.6667
2: B 28.66667 68333.33 3 111.6667
3: C 29.00000 53333.33 1 101.6667
在这里,每一列都是单独聚合的。虽然它需要更多的打字,但它有几个好处:
- 很容易理解代码 sn-p 的用途。
- 可以根据需要修改结果中的列名。
- 如果需要,可以控制结果中列的顺序。
变体 2
如果有许多列需要相同的操作,data.table 常见问题解答recommends 使用.SDcols。所以,我们可以做
m_cols <- c("Age", "Wages", "Productivity")
s_cols <- c("Education.University")
by_cols <- c("Company")
setDT(df)[, c(.SD[, lapply(.SD, mean), .SDcols = m_cols],
.SD[, lapply(.SD, sum ), .SDcols = s_cols]),
by = by_cols]
Company Age Wages Productivity Education.University
1: A 27.00000 56666.67 102.6667 2
2: B 28.66667 68333.33 111.6667 3
3: C 29.00000 53333.33 101.6667 1
这类似于 Akrun's answer,但使用列 names 而不是列 numbers。此外,列名存储在一个便于编程的变量中。
请注意,by_cols 可能包含用于聚合的其他列,例如,
by_cols <- c("Company", "Name")
如果列顺序很重要,我们可以使用setcolorder():
result <- setDT(df)[, c(.SD[, lapply(.SD, mean), .SDcols = m_cols],
.SD[, lapply(.SD, sum ), .SDcols = s_cols]),
by = by_cols]
setcolorder(result, intersect(names(df), names(result)))
result
Company Age Wages Education.University Productivity
1: A 27.00000 56666.67 2 102.6667
2: B 28.66667 68333.33 3 111.6667
3: C 29.00000 53333.33 1 101.6667
同样,可以修改结果的列名以满足OP的要求:
setnames(result, m_cols, paste0("average.", m_cols))
setnames(result, s_cols, paste0("sum.", s_cols))
result
Company average.Age average.Wages sum.Education.University average.Productivity
1: A 27.00000 56666.67 2 102.6667
2: B 28.66667 68333.33 3 111.6667
3: C 29.00000 53333.33 1 101.6667
请注意,data.table 函数 setcolorder() 和 setnames() 工作就地,即不复制 data.table 对象。这可以节省内存和时间,这在处理大型表时尤为重要。