计算小计(总和,stdev,平均等)

时间:2012-09-27 09:32:26

标签: r dataframe subtotal

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

样本数据集:

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

我想做的是相当直接的。我想总结(或平均或stdev)数量列。但是,我也希望在以下条件下进行相同的操作:

  1. VarName包含“Apple”
  2. VarName包含“Ugly”
  3. 颜色等于“蓝色”
  4. 有谁可以快速介绍一下如何进行这种计算?

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

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

    然而,我相信有更直接的方式来做到这一点。是否有一些过滤器可以添加到sum()等函数中?

2 个答案:

答案 0 :(得分:2)

分割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))

答案 1 :(得分:1)

这是你要找的吗?

 # 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])