平均

2012-06-07 169 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位,因此增加了「遞減=真」部分。 –