我有一个非常大的数据集(数百万行),当NA
等于" Z"时,我需要转换为var1
某些行。但是,我还需要将前一行NA
变为var1="Z"
行。
E.g:
id var1
1 A
1 B
1 Z
1 S
1 A
1 B
2 A
2 B
3 A
3 B
3 A
3 B
4 A
4 B
4 A
4 B
在这种情况下,id==1
的第二行和第三行应为NA
。
我尝试了一个循环,但它不起作用,因为数据集非常大。
for (i in 1:length(df$var1)){
if(df$var1[i] =="Z"){
df[i,] <- NA
df[(i-1),] <-- NA
}
}
我也尝试过使用data.table包失败。您是否知道我该怎么做?或者您正在寻找有关我想要做的信息的正确术语是什么?
答案 0 :(得分:2)
也许这样使用data.table:
df <- as.data.table(read.table(header=T, file='clipboard'))
df$var1 <- as.character(df$var1)
#find where var1 == Z
index <- df[, which(var1 == 'Z')]
#add the previous lines too
index <- c(index, index-1)
#convert to NA
df[index, var1 := NA ]
或者在一个电话中:
df[c(which(var1 == 'Z'), which(var1 == 'Z') - 1), var1 := NA ]
输出:
> df
id var1
1: 1 A
2: 1 NA
3: 1 NA
4: 1 S
5: 1 A
6: 1 B
7: 2 A
8: 2 B
9: 3 A
10: 3 B
11: 3 A
12: 3 B
13: 4 A
14: 4 B
15: 4 A
16: 4 B
答案 1 :(得分:2)
如果您想要计算前面的索引,只要它们来自同一个id
,我建议使用.I
和by
组合来确保您没有从之前的id
setDT(df)[, var1 := as.character(var1)]
indx <- df[, {indx <- which(var1 == "Z") ; .I[c(indx - 1L, indx)]}, by = id]$V1
df[indx, var1 := NA_character_]
df
# id var1
# 1: 1 A
# 2: 1 NA
# 3: 1 NA
# 4: 1 S
# 5: 1 A
# 6: 1 B
# 7: 2 A
# 8: 2 B
# 9: 3 A
# 10: 3 B
# 11: 3 A
# 12: 3 B
# 13: 4 A
# 14: 4 B
# 15: 4 A
# 16: 4 B
答案 2 :(得分:1)
您可以采用基本R
方法:
x = var1=='Z'
df[x | c(x[-1],F), 'var1'] <- NA
# id var1
#1 1 A
#2 1 <NA>
#3 1 <NA>
#4 1 S
#5 1 A
#6 1 B
#7 2 A
#8 2 B
#9 3 A
#10 3 B
#11 3 A
#12 3 B
#13 4 A
#14 4 B
#15 4 A
#16 4 B