【问题标题】:Calculating subtotals (sum, stdev, average etc)计算小计(sum、stdev、average 等)
【发布时间】:2012-09-19 01:20:21
【问题描述】:

我一直在寻找这个,但到目前为止还没有找到明确的答案。可能一直在寻找错误的条款,但也许这里有人可以快速帮助我。这个问题有点基本。

样本数据集:

set <- structure(list(VarName = structure(c(1L, 5L, 4L, 2L, 3L),
 .Label = c("Apple/Blue/Nice", 
"Apple/Blue/Ugly", "Apple/Pink/Ugly", "Kiwi/Blue/Ugly", "Pear/Blue/Ugly"
), class = "factor"), Color = structure(c(1L, 1L, 1L, 1L, 2L), .Label = c("Blue", 
"Pink"), class = "factor"), Qty = c(45L, 34L, 46L, 21L, 38L)), .Names = c("VarName", 
"Color", "Qty"), class = "data.frame", row.names = c(NA, -5L))

这给出了如下数据集:

set


      VarName      Color Qty
1 Apple/Blue/Nice  Blue  45
2  Pear/Blue/Ugly  Blue  34
3  Kiwi/Blue/Ugly  Blue  46
4 Apple/Blue/Ugly  Blue  21
5 Apple/Pink/Ugly  Pink  38

我想做的是相当直截了当。我想对 Qty 列求和(或平均值或标准差)。但是,我也想在以下条件下做同样的操作:

  1. VarName 包括“Apple”
  2. VarName 包含“丑陋”
  3. 颜色等于“蓝色”

谁能给我快速介绍一下如何执行这种计算?

我知道其中一些可以通过 aggregate() 函数完成,例如:

aggregate(set[3], FUN=sum, by=set[2])[1,2]

但是,我相信还有比这个更直接的方法。是否有一些过滤器可以添加到sum()等函数中?

【问题讨论】:

    标签: r dataframe subtotal


    【解决方案1】:

    拆分VarName 列的最简单方法,然后子集变得非常容易。所以,让我们创建一个对象被varName 分开:

    ##There must(?) be a better way than this. Anyone?
    new_set =  t(as.data.frame(sapply(as.character(set$VarName), strsplit, "/")))
    

    简要说明:

    • 我们使用as.character,因为set$VarName 是一个因素
    • sapply 依次获取每个值并应用 strplit
    • strsplit 函数拆分元素
    • 我们转换成数据框
    • 转置以获得正确的旋转

    接下来,

    ##Convert to a data frame
    new_set = as.data.frame(new_set)
    ##Make nice rownames - not actually needed
    rownames(new_set) = 1:nrow(new_set)
    ##Add in the Qty column
    new_set$Qty = set$Qty
    

    这给了

    R> new_set
         V1   V2   V3 Qty
    1 Apple Blue Nice  45
    2  Pear Blue Ugly  34
    3  Kiwi Blue Ugly  46
    4 Apple Blue Ugly  21
    5 Apple Pink Ugly  38
    

    现在所有的操作都是标准的。例如,

    ##Add up all blue Qtys
    sum(new_set[new_set$V2 == "Blue",]$Qty)
    [1] 146
    
    ##Average of Blue and Ugly Qtys
    mean(new_set[new_set$V2 == "Blue" & new_set$V3 == "Ugly",]$Qty)
    [1] 33.67
    

    一旦格式正确,您就可以使用ddply,它可以满足您的所有需求(以及更多)

    library(plyr)
    ##Split the data frame up by V1 and take the mean of Qty
    ddply(new_set, .(V1), summarise, m = mean(Qty))
    
    ##Split the data frame up by V1 & V2 and take the mean of Qty
    ddply(new_set, .(V1, V2), summarise, m = mean(Qty))
    

    【讨论】:

    • 感谢您的解释。在学习的过程中,我发现了一些东西。这似乎给出了一个 NaN 答案:“mean(new_set[new_set$V2 == "Blue" && new_set$V3 == "Ugly",]$Qty)"。不确定为什么会这样。
    • @Jochem Opps,我有&amp;&amp; 而不是&amp;&amp;&amp; 不适合矢量。
    【解决方案2】:

    这是你要找的吗?

     # sum for those including 'Apple'
     apple <- set[grep('Apple', set[, 'VarName']), ]
     aggregate(apple[3], FUN=sum, by=apple[2])
      Color Qty
    1  Blue  66
    2  Pink  38
    
     # sum for those including 'Ugly'
     ugly <- set[grep('Ugly', set[, 'VarName']), ]
     aggregate(ugly[3], FUN=sum, by=ugly[2])
      Color Qty
    1  Blue 101
    2  Pink  38
    
     # sum for Color==Blue
     sum(set[set[, 'Color']=='Blue', 3])
    [1] 146
    

    最后的总和可以使用subset完成

    sum(subset(set, Color=='Blue')[,3])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2022-11-11
      相关资源
      最近更新 更多