按照两个变量聚合一个值

3
我有一个类似于下面的数据框:

AgeBracket    No of People     No of Jobs
18-25               2               5
18-25               2               2
26-34               4               6
35-44               4               0
26-34               2               3 
35-44               1               7
45-54               3               2

我希望你能将数据聚合起来,使其看起来像下面这样:

AgeBracket     1Person    2People    3People    4People
18-25             0          3.5        0          0
26-34             0           3         0          6
35-44             7           0         0          0
45-54             0           0         2          0

所以沿着Y轴是年龄段,沿着X(顶行)是人数,而在单元格中显示的是该年龄段和人数的平均工作数量。

我认为这与聚合有关,但在任何网站上都找不到类似的内容。

2个回答

4

这里是使用 dcast 的 data.table 方法。

library(data.table)

setnames(dcast(df, AgeBracket ~ People, value.var="Jobs", fun.aggregate=mean, fill=0),
         c("AgeBracket", paste0(sort(unique(df$People)), "Person")))[]

在这里,dcast 用于重塑数据,将人员作为单独的变量。使用 fun.aggregate 计算不同年龄段和人员组合下的工作平均数。 fill 设置为0。 setnames 用于重命名变量,因为默认值是整数值。在末尾使用 [] 打印结果。
   AgeBracket 1Person 2Person 3Person 4Person
1:      18-25       0     3.5       0       0
2:      26-34       0     3.0       0       6
3:      35-44       7     0.0       0       0
4:      45-54       0     0.0       2       0

这段文字可以分成两行,这样更易于阅读。

# reshape wide and calculate means
df.wide <- dcast(df, AgeBracket ~ People, value.var="Jobs", fun.aggregate=mean, fill=0)
# rename variables
setnames(df.wide, c("AgeBracket", paste0(names(df.wide)[-1], "Person")))

我需要哪个包/库来使用dcast? - MLPNPC
抱歉,这个版本的 dcast 是来自于 data.table - lmo
reshape2中的dcast函数可能也可以不做(太多)更改就能使用,但是setnames是一个用于重命名变量的data.table函数。 - lmo

3

假设df是您的数据框,则可以使用BaseR中的平均函数进行聚合,但我认为Imo建议的data.table方法更快:

agg <- aggregate(No.of.Jobs ~ AgeBracket + No.of.People,data=df,mean)
fin <- reshape2::dcast(agg,AgeBracket ~ No.of.People)
fin[is.na(fin)] <- 0
names(fin) <- c("AgeBracket",paste0("People",1:4))

根据@Imo的建议,可以用一行代码实现:

reshape2::dcast(df, AgeBracket ~ No.of.People, value.var="No.of.Jobs", fun.aggregate=mean, fill=0)

我们只需要在此之后重命名列。

输出:

 AgeBracket People1 People2 People3 People4
1      18-25       0     3.5       0       0
2      26-34       0     3.0       0       6
3      35-44       7     0.0       0       0
4      45-54       0     0.0       2       0

1
请注意,此处的 dcast 语法与 data.table(v1.10.4)和 reshape2(v1.4.1)包相同,因此您的前三行可以合并为我的第一行,如 reshape2::dcast(df, AgeBracket ~ People, value.var="Jobs", fun.aggregate=mean, fill=0)。这是我给你的额外建议。 - lmo
@Imo 感谢您的回复,总是很高兴听到专家的意见。我认为 data.table 的解决方案更好,我知道您想要传达什么,我只是试图让解决方案更简单。 - PKumar
1
当然。除了速度之外,data.tabledcast的第二个优点是它可以一次转换多个变量,在更宽的数据集中非常方便。 - lmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接