R数据框。它有大约十几列和150行左右。在这两个条件下,我想遍历每一行并将其删除
我的代码看起来像这样,但它一直在崩溃。这是一个愚蠢的错误,但我无法弄明白。
for (i in 2:nrow(newfile)){
if (is.na(newfile[i,8]) && !is.na(newfile[(i-1),8]){
newfile<-newfile[-i,]
}
}
显然在这个例子中,newfile是我的数据帧。
我得到的错误
[.data.frame
中的错误(newfile,-i,):找不到对象
问题解决了,但是如果你们想要捣乱的话,还有一些测试数据:
23 L8 29141078 744319 27165443
24 L8 27165443 NA NA
25 L8 28357836 8293 25116398
26 L8 25116398 NA NA
27 L8 28357836 21600 25116398
28 L8 25116398 NA NA
29 L8 40929564 NA NA
30 L8 40929564 NA NA
31 L8 41917264 33234 39446503
32 L8 39446503 NA NA
33 L8 41917264 33981 39446503
34 L8 39446503 NA NA
这里显然有点修改,现在你将第4列与上面的第4列进行比较(或者你可以使用第5列,无论哪种方式)
答案 0 :(得分:2)
问题是你正在从自己身下改变数据框; nrow(newfile)
的原始评估不会随着你的进展而更新(如果你有一个C风格的循环for (i=1; i<=nrow(newfile); i++)
......)。另一方面,在while
循环中,每次循环都会重新评估条件,所以我认为这样可行。
i <- 2
while (i<=nrow(newfile)){
if (is.na(newfile[i,8]) && !is.na(newfile[i-1,8])) {
newfile<-newfile[-i,]
}
i <- i+1
}
你没有给我们一个容易重复的答案(即带答案的测试数据集),所以我现在不打算对此进行测试。
仔细思考(我现在没时间给出这一点)可能导致非迭代(因此可能非常快,如果重要的话)这样做。
答案 1 :(得分:0)
Error in if (is.na(newfile[i,8]) && !is.na(newfile[(i-1),8]) { :
missing value where TRUE/FALSE needed
这是因为你在迭代行时会删除行,所以当你到达nrow(newfile)
时(这是原始的行数,因为nrow(newfile)
被评估一次在foor循环的开头),它可能不再存在,因为行已被删除。
您可以通过构造要保留哪些行的逻辑索引来完全避免循环(例如,如果要保留行,则nrow(newfile)
的长度为TRUE
,否则为FALSE
:
n <- nrow(newfile)
# first bit says "is the row NA (for rows 2:n)"
# second bit says "is the row above *not* NA (for rows 1:(n-1))
# the & finds rows satisfying *both* conditions (first row always gets kept)
toRemove <- c(FALSE,is.na(newfile[-1,8])) & c(FALSE,!is.na(newfile[-n,8]))
toKeep <- !toRemove
newfile <- newfile[toKeep,]
如果那是你的话,你可以在一行中完成所有这些:
newfile <- newfile[ !(c(FALSE,is.na(newfile[-1,8])) & c(FALSE,!is.na(newfile[-nrow(newfile),8]))), ]
答案 2 :(得分:0)
这是另一种解决方案。但如果前一个值也是NA,它会保留NA值。
#create some dummy data
newfile <- matrix(runif(800), ncol = 8)
newfile[rbinom(100, 1, 0.25) == 1, 8] <- NA
#the selection
newfile[-which(diff(is.na(newfile[, 8])) == 1) - 1, ]