递增计算数据框中唯一数据点的有效方法

Efficient Way to Incrementally Count Unique Data Points in Data Frame

我正在尝试寻找一种更有效的方法来增量计算数据框中的唯一数据点。

比如我写了下面的代码:

df = matrix(c(1,2,3,3,4,5,1,2,4,4))

count = matrix(nrow = nrow(df),ncol=1)

for (i in 1:nrow(df)) {

  count[i,1] = length(which(df[1:i,1] == df[i,1]))

}

代码的目的是递增地计算特定值的每个实例,例如count 列将有以下结果:

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

到目前为止我编写的代码可以完成这项工作,但是上面的示例 df 只包含 10 个值。我试图在其上执行此功能的真实数据框包含 52,118 values,这需要大量时间。

有人知道执行上述代码的更有效方法吗?

这是使用 dplyr 包的快速方法:

library(dplyr)

# Fake data
set.seed(20)
dat  = data.frame(values = sample(1:3, 50000, replace=TRUE))

dat %>% group_by(values) %>%
  mutate(runningCount = 1:n())

   values runningCount
1       2            1
2       3            1
3       1            1
4       3            2
5       1            2
6       3            3
7       3            4
..    ...          ...

计时(以毫秒为单位):

     min       lq     mean   median       uq      max  neval
2.003755 2.134762 2.198161 2.186214 2.231662 3.665328    100

到目前为止所有答案的时间(使用我创建的数据):

                median
        dplyr:   2.11
   data.table:   1.24
lapply/Reduce:  11.61
          ave:   9.93

所以data.table是最快的。

一个基地R方法:

Reduce(`+`,lapply(unique(c(df)), function(u){b=c(df)==u;b[b==T]=cumsum(b[b==T]);b}))
#[1] 1 1 1 2 1 1 2 2 2 3

data.table解决方案

library(data.table)
set.seed(20)
dat  <-data.frame(values = sample(1:3, 50000, replace=TRUE))
setDT(dat)[,runningCount:=1:.N,values]

       values runningCount
    1:      3            1
    2:      3            2
    3:      1            1
    4:      2            1
    5:      3            3
   ---                    
49996:      1        16674
49997:      2        16516
49998:      2        16517
49999:      2        16518
50000:      2        16519