【问题标题】:How do I split a data frame by a specific column value, and then apply functions to columns within the data set?如何按特定列值拆分数据框,然后将函数应用于数据集中的列?
【发布时间】:2014-07-07 18:00:38
【问题描述】:

我有一个包含 3 列描述帐户的数据框:

年龄、用户和费用

年龄列的范围是 1-20,我想做的是按年龄计算平均成本,然后除以平均用户年龄。

例如,所有年龄为 1 岁的用户的平均数量是多少,以及年龄为 1 岁的帐户的平均成本是多少。

数据框很大,我不希望只输入 df = data[data$age_month == 1,] 然后将平均值应用于 1 到 1 列。

Age  Users   Cost
1     2       5
2     15      7
2     124     10
2     43      100
3     232     21212
4     234     21212 
4     12      10000 
4     10      3
5     11      89
6     4       11
6     8       12
6     10      15

所以我想要年龄 = 1 的平均成本列除以年龄 = 1 的用户列的平均值以及所有年龄的列

提前致谢,

【问题讨论】:

标签: r


【解决方案1】:

试试:

CostbyAge <- with(dat, ave(Cost, Age, FUN=mean) )
UsersbyAge <- with(dat, ave(Users, Age, FUN=mean))
CostbyAge/UsersbyAge
# [1]   2.5000000   0.6428571   0.6428571   0.6428571  91.4310345 121.9335938
# [7] 121.9335938 121.9335938   8.0909091   1.7272727   1.7272727   1.7272727

【讨论】:

  • nvm 忽略之前的评论
【解决方案2】:

这是使用dplyr 的一种方法:

library(dplyr)

dat %>%
  group_by(Age) %>%
  summarize(count=length(Age),
            users_mean=round(mean(Users),2),
            cost_mean=round(mean(Cost),2),
            cost_per_user=round(cost_mean/users_mean,2))

  Age count users_mean cost_mean cost_per_user
1   1     1       2.00      5.00          2.50
2   2     3      60.67     39.00          0.64
3   3     1     232.00  21212.00         91.43
4   4     3      85.33  10405.00        121.94
5   5     1      11.00     89.00          8.09
6   6     3       7.33     12.67          1.73

【讨论】:

  • 刚刚看到您的dplyr 代码。我删除了我创建的那个。
【解决方案3】:

data.table解决方案

library(data.table)
setDT(dat)[, list(User_mean = mean(Users), 
                  Mean_Cost = mean(Cost), 
                  Cost_per_User = mean(Cost)/mean(Users)), by = Age]

基础 R,使用 aggregate

aggdat <- aggregate(cbind(Users, Cost) ~ Age, dat,  mean)
aggdat$Cost_per_User <- aggdat$Cost/aggdat$Users

【讨论】:

    【解决方案4】:

    这是一种使用doBy::summaryBy 的方法。假设 dat 是您的样本数据

    > library(doBy)
    > ( s <- summaryBy(Users+Cost~Age, data = dat) )
    #   Age Users.mean   Cost.mean
    # 1   1   2.000000     5.00000
    # 2   2  60.666667    39.00000
    # 3   3 232.000000 21212.00000
    # 4   4  85.333333 10405.00000
    # 5   5  11.000000    89.00000
    # 6   6   7.333333    12.66667
    > s$Cost.mean / s$Users.mean
    # [1]   2.5000000   0.6428571  91.4310345 121.9335938   8.0909091   1.7272727
    

    【讨论】:

      【解决方案5】:

      由于没有人提及,您也可以使用 base R splitlapply 结合使用:

      > lapply(split(dat,dat$Age),colMeans)
      

      要将结果输出为数据框而不是列表将需要这个额外的步骤:

      > do.call(rbind,lapply(split(dat,dat$Age),colMeans))
        Age      Users        Cost
      1   1   2.000000     5.00000
      2   2  60.666667    39.00000
      3   3 232.000000 21212.00000
      4   4  85.333333 10405.00000
      5   5  11.000000    89.00000
      6   6   7.333333    12.66667
      

      split 获取您的数据框并创建相应拆分的数据框列表,然后使用lapply 您一次对所有子数据框进行操作(这里计算您可以简单地使用colMeans 的平均值)。然后do.call(rbind,...) 获取您的结果列表并将其转回数据框。

      获取每位用户费用的最后一步与其他解决方案相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-10
        • 1970-01-01
        • 1970-01-01
        • 2017-08-20
        • 2021-09-06
        • 1970-01-01
        • 2019-05-06
        相关资源
        最近更新 更多