【问题标题】:Aggregate a value by 2 variables通过 2 个变量聚合一个值
【发布时间】:2017-05-09 12:55:48
【问题描述】:

我有一个看起来像这样的数据框

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(顶行)是人数,而在单元格中显示的是该年龄组的平均工作数量和人数。

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

【问题讨论】:

    标签: r variables aggregate multiple-columns


    【解决方案1】:

    这是一个使用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 用于计算 ageBracket-person 单元格中的平均工作数。填充设置为 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 需要哪个包/库?
    • 对不起。补充一下,这个版本的dcast来自data.table
    • reshape2 中的 dcast 函数可能也可以在没有(m)任何更改的情况下工作,但 setnames 是用于重命名变量的 data.table 函数。
    【解决方案2】:

    假设 df 是您的 data.frame,那么您可以使用 BaseR 将聚合与平均函数一起使用,但我认为 data.table 方式比 Imo 建议的更快:

    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
    

    【讨论】:

    • 请注意 dcast 的语法在这种情况下是相同的 data.table (v 1.10.4) 和 reshape2 (v 1.4.1) 包,所以你的前三行可以折叠到我的第一行,比如reshape2::dcast(df, AgeBracket ~ People, value.var="Jobs", fun.aggregate=mean, fill=0)。加我一个。
    • @Imo 很高兴听到专家的来信,我认为 data.table 解决方案要好得多,我知道您要传达的内容我只是想让解决方案变得简单。
    • 当然可以。除了速度之外,data.tabledcast 的第二个优势是它可以一次转换多个变量,这在更广泛的数据集中非常方便。
    猜你喜欢
    • 2017-10-26
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多