2010-12-20 29 views
4

假設我有一個向量,我不知道,先驗,它的獨特元素(在這裏:1和2)。有沒有更好的方式獲得相同的輸出表(vec)vec是矢量?

vec <- 
    c(1, 1, 1, 2, 2, 2, 2) 

我想知道有沒有獲取在vec即相同的結果table(vec)獨特元件的數量的一個更好的方式(或優雅的方式)。無論它是一個data.frame還是一個命名向量都沒關係。

R> table(vec) 
vec 
1 2 
3 4 

原因:我很好奇,想知道是否有更好的方法。另外,我注意到base實現中有一個for循環(除了.C調用)。我不知道這是一個大問題,但是當我做類似

R> table(rep(1:1000,100000)) 

R需要很長時間。我相信這是因爲數量龐大的100000.但是有沒有辦法讓它更快?

編輯這也做得不錯,除了Chase's的答案。

R> rle(sort(sampData)) 

回答

9

這是一個有趣的問題 - 我很想看到關於此的其他想法。查看table()的來源顯示它建立在tabulate()之外。 tabulate()顯然有一些怪癖,即它只處理正整數並返回一個沒有名字的整數向量。我們可以在我們的矢量上使用unique()來應用names()。如果你需要列表零或負值,我想回去檢查table()將是必要的,因爲tabulate()似乎並沒有按照幫助頁上的例子。

table2 <- function(data) { 
    x <- tabulate(data) 
    y <- sort(unique(data)) 
    names(x) <- y 
    return(x) 
    } 

和快速測試:

> set.seed(42) 
> sampData <- sample(1:5, 10000000, TRUE, prob = c(.3,.25, .2, .15, .1)) 
> 
> system.time(table(sampData)) 
    user system elapsed 
    4.869 0.669 5.503 
> system.time(table2(sampData)) 
user system elapsed 
0.410 0.200 0.605 
> 
> table(sampData) 
sampData 
     1  2  3  4  5 
2999200 2500232 1998652 1500396 1001520 
> table2(sampData) 
     1  2  3  4  5 
2999200 2500232 1998652 1500396 1001520 

編輯:我只是意識到存在plyr一個count()功能這是另一種替代table()。在上面的測試中,它的性能比table()好,並且比我放在一起的黑客解決方案稍差:

library(plyr) 
system.time(count(sampData)) 
    user system elapsed 
    1.620 0.870 2.483 
+0

謝謝你的好解決方案。其實,我也在思考這個問題。我很好奇,如果有使用lapply或(根據我的喜好)使用plyr的函數(彙總等)的解決方案。 (我知道lapply不一定會提高速度) – suncoolsu

+2

@suncoolsu - 你見過'plyr'的count()嗎?我之前並沒有意識到這一點,但您的評論讓我失望地找到了一條尋找它的途徑。可能是另一個可行的替代方案。 – Chase

+2

那麼'unique'內的'sort'是多餘的;刪除它給了我這個數據上'table2'的3倍加速。 – mbq

相關問題