从R中的向量创建频率计数

时间:2014-01-01 14:00:43

标签: r vector

假设存在具有可能重复值的数值的向量

x <- c(1, 2, 3, 4, 5, 1, 2, 2, 3)

我想创建另一个计数向量,如下所示。

  1. 它与x的长度相同。
  2. 对于x中的每个唯一值,第一个外观为1,第二个外观为2,依此类推。
  3. 我想要的新矢量是

    1, 1, 1, 1, 1, 2, 2, 3, 2
    

    我需要一种快速的方法,因为x可能很长。

1 个答案:

答案 0 :(得分:8)

使用aveseq_along

> x <- c(1, 2, 3, 4, 5, 1, 2, 2, 3)
> ave(x, x, FUN = seq_along)
[1] 1 1 1 1 1 2 2 3 2

另一个需要考虑的选择是data.table。虽然这是一项更多的工作,但它可能会在非常长的向量上得到回报。

这是你的例子 - 看起来有点矫枉过正!

library(data.table)

x <- c(1, 2, 3, 4, 5, 1, 2, 2, 3)
DT <- data.table(id = sequence(length(x)), x, key = "id")
DT[, y := sequence(.N), by = x][, y]
# [1] 1 1 1 1 1 2 2 3 2

但是对于10,000,000个项目的长度来说怎么样?

set.seed(1)
x2 <- sample(100, 1e7, replace = TRUE)

funAve <- function() {
  ave(x2, x2, FUN = seq_along)
}

funDT <- function() {
  DT <- data.table(id = sequence(length(x2)), x2, key = "id")
  DT[, y := sequence(.N), by = x2][, y]
}

identical(funAve(), funDT())
# [1] TRUE

library(microbenchmark)
# Unit: seconds
#      expr      min       lq   median       uq      max neval
#  funAve() 6.727557 6.792743 6.827117 6.992609 7.352666    20
#   funDT() 1.967795 2.029697 2.053886 2.070462 2.123531    20