1

说我有数据框

df <- data.frame('A' = c('a','a','a','a','b','b','b','b','b'),
                 'B' = c('y','y','z','z','y','y','y','z','z'),
                 'value'=c(1  , 2 , 2 , 3 , 2 , 3 , 1 , 2 , 2))

所以看起来像这样

 A B value  
 a y     1  
 a y     2  
 a z     2  
 a z     3  
 b y     2  
 b y     3  
 b y     1   
 b z     2   
 b z     2  

我可以使用查询获得 A 和 B 的每个子集的平均值

with(df, aggregate(df, by = list(A, B), FUN = mean))

经过一些操作后

A B value  
a y   1.5  
b y   2.0  
a z   2.5  
b z   2.0  

有没有办法做到这一点,但只计算每个子集中最高 x 值的平均值。因此,如果我们在此示例中将 x 设为 2,则子集 ay、az 和 bz 的平均值不会改变,因为它们总共只有两个条目(因此顶部 x 条目是子集的整个数据集)。但是 by 有三个条目,因此我们希望返回最高两个值(2 和 3)的平均值,以便输出表看起来像

A B value  
a y   1.5  
b y   2.5  
a z   2.5  
b z   2.0  
4

3 回答 3

2

我发现使用公式接口更容易aggregate,如下:

您的原始版本:

aggregate(value~A+B, data=df, FUN = mean)
  A B value
1 a y   1.5
2 b y   2.0
3 a z   2.5
4 b z   2.0

您可以通过使用计算排序值尾部平均值的匿名函数来获得所需的版本:

aggregate(value~A+B, data=df, FUN = function(x)mean(tail(sort(x), 2)))
  A B value
1 a y   1.5
2 b y   2.5
3 a z   2.5
4 b z   2.0
于 2012-06-07T16:08:13.800 回答
2

对于同一件事的版本:

lapply(split(df, list(df$A, df$B)),
       function(x) mean(x[order(x$value, decreasing = TRUE), ][1:2, "value"]))

或者

sapply(split(df, list(df$A, df$B)),
       function(x) mean(x[order(x$value, decreasing = TRUE), ][1:2, "value"]))

给出想要的结果:

> lapply(split(df, list(df$A, df$B),
+        function(x) mean(x[order(x$value, decreasing = TRUE), ][1:2, "value"]))
$a.y
[1] 1.5

$b.y
[1] 2.5

$a.z
[1] 2.5

$b.z
[1] 2

> sapply(split(df, list(df$A, df$B)),
+        function(x) mean(x[order(x$value, decreasing = TRUE), ][1:2, "value"]))
a.y b.y a.z b.z 
1.5 2.5 2.5 2.0

在实际应用程序中,您可能希望使匿名函数成为适当的函数,并使其对每个子集中少于 2 行的情况具有鲁棒性。这留给读者作为练习。

我展示的匿名函数(或一个非常相似的函数)可以很容易地用于aggregate()

aggregate(value ~ A + B, data = df,
          FUN = function(x) mean(x[order(x, decreasing = TRUE)][1:2]))

例如:

> aggregate(value ~ A + B, data = df,
+           FUN = function(x) mean(x[order(x, decreasing = TRUE)][1:2]))
  A B value
1 a y   1.5
2 b y   2.5
3 a z   2.5
4 b z   2.0

但我是老派,经常用手做这些事情。

于 2012-06-07T16:10:39.367 回答
0

这有帮助吗?

x <- 2
with(df, aggregate(df, by = list(A, B), FUN = function(x)
                                                 mean(x[1:x])))
于 2012-06-07T16:06:10.667 回答