平均

2012-06-07 122 views
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 

我可以得到的每个子集的均值和使用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条目是子集的整个数据集)。然而,通过有三个条目,所以我们希望回到最高的两个值(2,3),以便输出表看起来像

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

回答

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 
+0

简单而整洁,加上'tail()'用法,尽管'将sort ='递减为'TRUE'将允许使用'head()',这可能会清晰地表示代码的意图(或者可以使用' 1:2]') –

0

这是否帮助的是什么意思?

x <- 2 
with(df, aggregate(df, by = list(A, B), FUN = function(x) 
               mean(x[1:x]))) 
+0

不处理订购。 –

2

To ve的同样的事情rsions:

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 

但我老派和常做这些东西手工。

+0

该编辑解决了order()按默认顺序升序排序的问题,OP需要排在第2位,因此增加了“递减=真”部分。 –