是否有更好的方法获得与表(vec)相同的输出,其中vec是向量?

时间:2010-12-20 02:40:40

标签: r

假设我有一个向量,我不知道,apriori,它的独特元素(这里:1和2)。

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

我有兴趣知道在vec中获取唯一元素的数量是否更好(或优雅方式),即与table(vec)相同的结果。无论是data.frame还是命名向量都无关紧要。

R> table(vec)
vec
1 2 
3 4 

原因:我很想知道是否有更好的方法。另外,我注意到for实现中存在base循环(除了.C调用)。我不知道这是一个很大的问题,但是当我做一些像

这样的事情时
R> table(rep(1:1000,100000))

R需要很长时间。我确信这是因为它的数量很大。但有没有办法让它更快?

编辑Chase's答案外,这也做得很好。

R> rle(sort(sampData))

1 个答案:

答案 0 :(得分: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 

编辑:我刚刚意识到count()中有一个plyr函数,它是table()的另一种选择。在上面的测试中,它的性能优于table(),并且比我放在一起的黑客作业解决方案稍差:

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