我有一个大型的data.frame。 data.frame包含很多值。
例如:
df <- data.frame(Company = c('A', 'A', 'B', 'C', 'A', 'B', 'B', 'C', 'C'),
Name = c("Wayne", "Duane", "William", "Rafael", "John", "Eric", "James", "Pablo", "Tammy"),
Age = c(26, 27, 28, 32, 28, 24, 34, 30, 25),
Wages = c(50000, 70000, 70000, 60000, 50000, 70000, 65000, 50000, 50000),
Education.University = c(1, 1, 1, 0, 0, 1, 1, 0, 1),
Productivity = c(100, 120, 120, 95, 88, 115, 100, 90, 120))
如何汇总我的data.frame
?我想分析每家公司的价值观。它必须看起来像:
年龄 - &gt;公司所有员工的平均年龄
工资 - &gt;公司所有员工的平均工资
Education.University - &gt;公司所有员工的因子(1或0)之和
生产力 - &gt;公司所有员工的平均生产率
答案 0 :(得分:4)
基础R
cbind(aggregate(.~Company, df[,-c(2, 5)], mean),
aggregate(Education.University~Company, df, sum)[-1])
# 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
以下是可能更容易理解的较长版本
merge(x = aggregate(x = list(Age_av = df$Age,
Wages_av = df$Wages,
Productivity_av = df$Productivity),
by = list(Company = df$Company),
FUN = mean),
y = aggregate(x = list(Education.University_sum = df$Education.University),
by = list(Company = df$Company),
FUN = sum),
by = "Company")
# Company Age_av Wages_av Productivity_av Education.University_sum
#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
答案 1 :(得分:3)
一种选择是使用data.table
library(data.table)
setDT(df)[, c(lapply(.SD[, c(2:3, 5), with = FALSE], mean),
.(Education.University = sum(Education.University))), by = Company]
# 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
或dplyr
library(dplyr)
df %>%
group_by(Company) %>%
mutate(Education.University = sum(Education.University)) %>%
summarise_if(is.numeric, mean)
# A tibble: 3 x 5
# Company Age Wages Education.University Productivity
# <fctr> <dbl> <dbl> <dbl> <dbl>
#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
答案 2 :(得分:3)
您可以使用 dplyr 库轻松完成此操作。
library(dplyr)
df %>% group_by(Company) %>% summarise(Age = mean(Age), Wages = mean(Wages), Education.University = sum(Education.University), Productivity = mean(Productivity))
答案 3 :(得分:2)
简明data.table
解决方案已posted使用列数字而不是列名称。根据这被认为是不良做法
Frequently Asked Questions about data.table, section 1.1:
如果您的同事出现并稍后阅读您的代码,他们可能不得不四处寻找哪个列是5号。如果您或他们更改了R程序中更高的列排序,您可能会产生错误的结果如果您忘记更改代码中引用第5列的所有位置,则会出现警告或错误。
因此,我想提出使用列名的替代方法。
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
此处,每列都单独汇总。虽然它需要更多的打字,但它有几个好处:
如果有许多列需要相同的操作,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类似,但使用列名称而不是列数字。此外,列名存储在一个易于编程的变量中。
请注意,by_cols
可能包含其他要聚合的列,.e.g,
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
对象。这样可以节省内存和时间,这在处理大型表时尤其重要。
答案 4 :(得分:2)
只需使用“聚合”功能
aggregate(x = df[c("Age","Wages","Education.University","Productivity")], by = df[c("Company")], FUN = mean)
# Company Age Wages Education.University Productivity
#1 A 27.00000 56666.67 0.6666667 102.6667
#2 B 28.66667 68333.33 1.0000000 111.6667
#3 C 29.00000 53333.33 0.3333333 101.6667