假设我有以下数据框:
key values
A 118
B 118
B 118
C 100
A 90
A 90
A 90
我想用0替换上一行具有相同键的值。 然后,数据将是:
key values
A 118
B 118
B 0
C 100
A 90
A 0
A 0
对于名为'm'的数据框,我用于和if:
for (i in 1:(length(m[,1])-1)) {
if (m[,1][i+1]==m[,1][i]) {m[,2][i+1]<- 0}
}
它可以工作,但我的数据有2104776行和23列。所以,花了3个小时。
我想知道是否有更有效的方法来完成这项任务。任何想法,将不胜感激。谢谢。
答案 0 :(得分:5)
我们可以使用lag
中的dplyr
并检查key
中的值是否与之前的值相同,并为匹配的人分配0。
library(dplyr)
df$values[df$key == lag(df$key)] <- 0
df
# key value
#1 A 118
#2 B 118
#3 B 0
#4 C 100
#5 A 90
#6 A 0
#7 A 0
答案 1 :(得分:2)
在data.table
中,您可以使用rleid
进行分组,如下所示:
library(data.table)
setDT(df)
df[, values := c(head(values, 1), rep(0L, .N-1)), by=rleid(key)]
df
key values
1: A 118
2: B 118
3: B 0
4: C 100
5: A 90
6: A 0
7: A 0
c(head(values, 1), rep(0L, .N-1))
获取值的第一个元素,并将其前置为0的向量,即组的长度减去1。
答案 2 :(得分:1)
你基本上采用了密钥cols的cusmsum,然后减去这些密钥的长度索引,为你提供一个应该保存值的向量,你可以将其他所有内容转换为0.
i=cumsum(rle(as.character(df$key))$lengths)-(rle(as.character(df$key))$lengths-1)
df$values[-i]=0