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

4
假设有一个包含数字值的向量,其中可能存在重复的值。
x <- c(1, 2, 3, 4, 5, 1, 2, 2, 3)

我希望创建另一个计数向量,具体如下:

  1. 它的长度与 x 相同。
  2. 对于 x 中的每个唯一值,第一次出现为 1,第二次出现为 2,以此类推。

我想要的新向量是:

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

我需要一种快速的方法来处理这个问题,因为x可能非常长。

1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接