2013-01-21 96 views
10

aggregatehere的另一個問題進行實驗時,我遇到了一個相當奇怪的結果。我無法弄清楚爲什麼,想知道我在做什麼是完全錯誤的。集合的意外輸出

想,我有一個data.frame這樣的:

df <- structure(list(V1 = c(1L, 2L, 1L, 2L, 3L, 1L), 
        V2 = c(2L, 3L, 2L, 3L, 4L, 2L), 
        V3 = c(3L, 4L, 3L, 4L, 5L, 3L), 
        V4 = c(4L, 5L, 4L, 5L, 6L, 4L)), 
        .Names = c("V1", "V2", "V3", "V4"), 
     row.names = c(NA, -6L), class = "data.frame") 
> df 
# V1 V2 V3 V4 
# 1 1 2 3 4 
# 2 2 3 4 5 
# 3 1 2 3 4 
# 4 2 3 4 5 
# 5 3 4 5 6 
# 6 1 2 3 4 

現在,如果我要輸出一個額外列data.frame唯一行表明df它們的頻率。在這個例子中,

# V1 V2 V3 V4 x 
# 1 1 2 3 4 3 
# 2 2 3 4 5 2 
# 3 3 4 5 6 1 

我通過實驗得到如下使用aggregate輸出:

> aggregate(do.call(paste, df), by=df, print) 

# [1] "1 2 3 4" "1 2 3 4" "1 2 3 4" 
# [1] "2 3 4 5" "2 3 4 5" 
# [1] "3 4 5 6" 
# V1 V2 V3 V4       x 
# 1 1 2 3 4 1 2 3 4, 1 2 3 4, 1 2 3 4 
# 2 2 3 4 5   2 3 4 5, 2 3 4 5 
# 3 3 4 5 6     3 4 5 6 

所以,這給了我所粘貼的字符串。因此,如果我使用length而不是print,它應該給我這種情況的數量,這是期望的結果,情況如此(如下所示)。

> aggregate(do.call(paste, df), by=df, length) 
# V1 V2 V3 V4 x 
# 1 1 2 3 4 3 
# 2 2 3 4 5 2 
# 3 3 4 5 6 1 

而這似乎工作。但是,當data.frame尺寸爲4 * 2500時,輸出data.frame爲1 * 2501而不是4 * 2501(所有行都是唯一的,因此頻率爲1)。

​​

我與只是唯一行較小data.frames測試,它使右輸出(變化nrow=40,例如)。但是,當矩陣的尺寸增加時,這似乎不起作用。我只是無法弄清楚發生了什麼問題!有任何想法嗎?

+2

也許,因爲字符串變得太長而'as.character'插入換行符? – Roland

+0

是的,作爲一種替代方法,您可以執行'aggregate(rep(1,nrow(df)),df,FUN = length)'。 – flodel

+1

這與'as.character()'無關,因爲它的每個參數都是長度爲1的向量。要看到這部分工作,只需執行'do.call(paste,df [1:3,])'。 –

回答

10

這裏的問題是如何確定組aggregate.data.frame()

aggregate.data.frame()有一個循環,它形成了分組變量grp。在這種循環中,grp改變/經更新時間:

grp <- grp * nlevels(ind) + (as.integer(ind) - 1L) 

的問題與你的榜樣,如果一旦by轉化爲因素,循環已經超過這些因素都,在你的榜樣grp結束向上存在:

Browse[2]> grp 
[1] Inf Inf Inf Inf 

本質上循環更新推的grp值到多個從Inf難以區分。

已經這樣做了,aggregate.data.frame()後來做到這一點

y <- y[match(sort(unique(grp)), grp, 0L), , drop = FALSE] 

而這正是先前的問題,現在表現爲

dim(y[match(sort(unique(grp)), grp, 0L), , drop = FALSE]) 

因爲

match(sort(unique(grp)), grp, 0L) 

顯然只返回1

> match(sort(unique(grp)), grp, 0L) 
[1] 1 

因爲只有一個唯一值grp

+1

只有'by'形成了太多的羣體。我不建議你這樣做,但另一種看待問題的方式是形成聚合的子數據幀,它可以處理'grp'沒有去'Inf':'length(split(do.call (paste,df),df))'。 **警告**,這將消耗您的所有內存(在我的4GB筆記本電腦上,我很快就會崩潰交換空間)。 –

+1

@阿倫是的,''''''''''''''''debugonce()'是你這種事情的朋友。 –