我正在尝试找到一种更有效的方法来逐步计算数据框中的唯一数据点。
例如,我编写了以下代码:
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]))
}
代码的目的是递增地计算特定值的每个实例,例如计数列将产生以下结果:
1,1,1,2,1,1,2,2,2,3.
到目前为止我编写的代码完成了这项工作,但上面的示例df只包含10个值。我试图执行此功能的实际数据框包含52,118 values
,这需要花费大量时间。
有谁知道一种更有效的方法来执行上面的代码?
答案 0 :(得分:9)
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
答案 1 :(得分:6)
这是使用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
是最快的。
答案 2 :(得分:6)
一种基础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