假设存在具有可能重复值的数值的向量
x <- c(1, 2, 3, 4, 5, 1, 2, 2, 3)
我想创建另一个计数向量,如下所示。
x
的长度相同。 x
中的每个唯一值,第一个外观为1,第二个外观为2,依此类推。我想要的新矢量是
1, 1, 1, 1, 1, 2, 2, 3, 2
我需要一种快速的方法,因为x
可能很长。
答案 0 :(得分:8)
使用ave
和seq_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