2014-03-13 16 views
0

我想創建兩個數據集,其中一個由2組,這是我用下面的代碼進行彙總數據:R:聚集在第1組和不羣2

x = rnorm(1:100) 
g1 = sample(LETTERS[1:3], 100, replace = TRUE) 
g2 = sample(LETTERS[24:26], 100, replace = TRUE) 

aggregate(x, list(g1, g2), mean) 

第二個需要總結數據由第一組而不是第二組。

如果我們考慮從前面的例子可能對:

A - X B - X C - X 
A - Y B - Y C - Y 
A - Z B - Z C - Z 

第二個數據集應數據總結爲平均值的類羣的。

A - not X 
A - not Y 
A - not Z etc. 

有沒有一種方法來操縱R中的聚合函數來實現這一點? 或者我也認爲可能有虛擬變量可以用這種方式表示數據,儘管我不確定它會如何顯示。

我發現這個答案在這裏: R using aggregate to find a function (mean) for "all other"

我認爲這表明每個配對一個虛擬變量是必要的。但是,如果有人能夠提供更好或更有效的方式,那將是值得讚賞的,因爲真實數據集中有許多配對。

在此先感謝

回答

2

首先,讓我們重複地生成數據(使用set.seed):

# same as question but added set.seed for reproducibility 
set.seed(123) 
x = rnorm(1:100) 
g1 = sample(LETTERS[1:3], 100, replace = TRUE) 
g2 = sample(LETTERS[24:26], 100, replace = TRUE) 

現在我們有兩種解決方案均使用匯總:

1)AVE

# x equals the sums over the groups and n equals the counts 
ag = cbind(aggregate(x, list(g1, g2), sum), 
      n = aggregate(x, list(g1, g2), length)[, 3]) 

ave.not <- function(x, g) ave(x, g, FUN = sum) - x 
transform(ag, 
    x = NULL, # don't need x any more 
    n = NULL, # don't need n any more 
    mean = x/n, 
    mean.not = ave.not(x, Group.1)/ave.not(n, Group.1) 
) 

這給出:

Group.1 Group.2  mean  mean.not 
1  A  X 0.3155084 -0.091898832 
2  B  X -0.1789730 0.332544353 
3  C  X 0.1976471 0.014282465 
4  A  Y -0.3644116 0.236706489 
5  B  Y 0.2452157 0.099240545 
6  C  Y -0.1630036 0.179833987 
7  A  Z 0.1579046 -0.009670734 
8  B  Z 0.4392794 0.033121335 
9  C  Z 0.1620209 0.033714943 

要仔細檢查下的平均值和下mean.not第一值:

> mean(x[g1 == "A" & g2 == "X"]) 
[1] 0.3155084 
> mean(x[g1 == "A" & g2 != "X"]) 
[1] -0.09189883 

2)sapply下面是其給出相同的答案第二種方法:

ag <- aggregate(list(mean = x), list(g1, g2), mean) 
f <- function(i) mean(x[g1 == ag$Group.1[i] & g2 != ag$Group.2[i]])) 
ag$mean.not = sapply(1:nrow(ag), f) 
ag 

修訂根據海報的意見修改,增加了第二種方法,還有m稍作改進。

+0

嗨,謝謝你的回答。如果你能解釋你的代碼是如何工作的,那將會很棒。雖然我認爲這不是我正在尋找的。如果結果正確,則應顯示A和Not X =平均值(AY和AZ)。 – SamPassmore

+0

在這種情況下,我修改了它。 –