根据分组字段和日期字段将序列号附加到数据框

时间:2014-04-08 17:16:16

标签: r

我试图将序列号附加到按个人和日期分组的数据框中。例如,转过来:

   x          y
1  A 2012-01-02
2  A 2012-02-03
3  A 2012-02-25
4  A 2012-03-04
5  B 2012-01-02
6  B 2012-02-03
7  C 2013-01-02
8  C 2012-02-03
9  C 2012-03-04
10 C 2012-04-05

到此:

   x          y v
1  A 2012-01-02 1
2  A 2012-02-03 2
3  A 2012-02-25 3
4  A 2012-03-04 4
5  B 2012-01-02 1
6  B 2012-02-03 2
7  C 2013-01-02 1
8  C 2012-02-03 2
9  C 2012-03-04 3
10 C 2012-04-05 4

其中“x”是个体,“y”是日期,“v”是附加序列号

我在这段代码中使用for循环在一个小数据框上取得了成功:

x=c("A","A","A","A","B","B","C","C","C","C")
y=as.Date(c("1/2/2012","2/3/2012","2/25/2012","3/4/2012","1/2/2012","2/3/2012",
"1/2/2013","2/3/2012","3/4/2012","4/5/2012"),"%m/%d/%Y")
x
y
z=data.frame(x,y)

z$v=rep(1,nrow(z))

for(i in 2:nrow(z)){
    if(z$x[i]==z$x[i-1]){
    z$v[i]=(z$v[i-1]+1)
    } else {
    z$v[i]=1
    }
}

但是当我将其扩展到更大的数据框(250K +行)时,这个过程将永远持续下去。

有关如何提高效率的任何想法?

2 个答案:

答案 0 :(得分:1)

这似乎有效。虽然可能有点矫枉过正。

## code needed revision - this is old code
## > d$v <- unlist(sapply(sapply(split(d, d$x), nrow), seq))

修改

我简直不敢相信我已经侥幸逃脱了这个丑陋的混乱。这是一个修订版。更简单。

## revised 04/24/2014
> d$v <- unlist(sapply(table(d$x), seq))
> d
##    x          y v
## 1  A 2012-01-02 1
## 2  A 2012-02-03 2
## 3  A 2012-02-25 3
## 4  A 2012-03-04 4
## 5  B 2012-01-02 1
## 6  B 2012-02-03 2
## 7  C 2013-01-02 1
## 8  C 2012-02-03 2
## 9  C 2012-03-04 3
## 10 C 2012-04-05 4

另外,一个有趣的是stack。看一看。

> stack(sapply(table(d$x), seq))
##    values ind
## 1       1   A
## 2       2   A
## 3       3   A
## 4       4   A
## 5       1   B
## 6       2   B
## 7       1   C
## 8       2   C
## 9       3   C
## 10      4   C

答案 1 :(得分:0)

我删除了之前的帖子并将其替换为此解决方案。对我来说非常有效。

# order data
z=z[order(z$x,z$y),]

#convert to data table
dt.z=data.table(z)

# obtain vector of sequence numbers
z$seq=dt.z[,1:.N,"x"]$V1

以上可以用更少的步骤完成,但我想说明我的所作所为。这是在一秒钟内将序列号附加到超过250k记录的数据集中。再次感谢Henrik和Richard。