我有一个按照姓名和时间排序的数据框。
set.seed(100)
df <- data.frame('name' = c(rep('x', 6), rep('y', 4)),
'time' = c(rep(1, 2), rep(2, 3), 3, 1, 2, 3, 4),
'score' = c(0, sample(1:10, 3), 0, sample(1:10, 2), 0, sample(1:10, 2))
)
> df
name time score
1 x 1 0
2 x 1 4
3 x 2 3
4 x 2 5
5 x 2 0
6 x 3 1
7 y 1 5
8 y 2 0
9 y 3 5
10 y 4 8
在
df$score
中有零值,后面跟着未知数量的实际值,例如df[1:4,]
。有时,在两个df$score == 0
之间会有重叠的df$name
,例如df[6:7,]
。我想在
df$score != 0
的情况下更改df$time
。具体来说,如果df$name
匹配,则我想分配最接近的上一行df$score == 0
的时间值。以下代码可以产生良好的输出,但我的数据有数百万行,因此这种解决方案效率非常低。
score_0 <- append(which(df$score == 0), dim(df)[1] + 1)
for(i in 1:(length(score_0) - 1)) {
df$time[score_0[i]:(score_0[i + 1] - 1)] <-
ifelse(df$name[score_0[i]:(score_0[i + 1] - 1)] == df$name[score_0[i]],
df$time[score_0[i]],
df$time[score_0[i]:(score_0[i + 1] - 1)])
}
> df
name time score
1 x 1 0
2 x 1 4
3 x 1 3
4 x 1 5
5 x 2 0
6 x 2 1
7 y 1 5
8 y 2 0
9 y 2 5
10 y 2 8
score_0
表示df$score == 0
的索引位置。我们可以看到,df$time[2:4]
现在都等于1,在df$time[6:7]
中只有第一个发生了变化,因为第二个满足df$name == 'y'
并且最接近的上一行满足df$score == 0
且df$name == 'x'
。最后两行也已正确更改。
df [ 7 , "time" ]
等于 **2
**,那么它会被更改为1
吗,因为它是name==y
的第一个条目,还是您会保持不变? - M--df$name
与最接近的df$score == 0
上方行不匹配。 - JPhset.seed
,这样每个人都可以获得相同的输出。祝福你,欢迎加入社区。 - M--set.seed()
技巧和整洁的答案! - JPh