我有一个如下数据库:
df <- data.frame(id=c(1,1,1,2,2,3,3,4),
num=c(12,12,12,28,28,17,17,7))
id num
1 1 12
2 1 12
3 1 12
4 2 28
5 2 28
6 3 17
7 3 17
8 4 7
我想每次id的另一行时将num的值增加1。我有以下代码可以做到这一点:
for (i in 2:nrow(df3)) {
if(df[i,1]==df[i-1,1]) {
df[i,2]=df[i-1,2]+1
}
}
这将导致如下所示的答案:
id num
1 1 12
2 1 13
3 1 14
4 2 28
5 2 29
6 3 17
7 3 18
8 4 7
此代码有效,但是我要处理的实际数据集有100亿行,因此效率很低。我尝试以不同方式使用lag()
中的dplry
函数,但没有成功。一种方法是从同一行的上一行获取ID进行比较,这是我的尝试:
df[,lag := shift(Id, 1L, type="lag")]
df[df$id==df$lag,2]<-shift(df[df$id==df$lag,2], 1L, type="lag")+1
但是,这显然不会运行。加快我的方法的任何帮助都将非常棒!谢谢。
答案 0 :(得分:2)
使用ave
df$num+ave(df$id,df$id,FUN = seq_along)-1
[1] 12 13 14 28 29 17 18 7
答案 1 :(得分:2)
library(data.table)
setDT(df)
df[, num := num + rowid(id) - 1L]
结果:
# id num
# 1: 1 12
# 2: 1 13
# 3: 1 14
# 4: 2 28
# 5: 2 29
# 6: 3 17
# 7: 3 18
# 8: 4 7
答案 2 :(得分:1)
如果您喜欢显式by
,请使用另一种data.table方法:
library(data.table)
setDT(df)
df[ , num := num + 1:.N - 1, by=id]