迭代R中的所有行,删除符合条件的行

时间:2012-01-30 02:37:07

标签: r row dataframe

R数据框。它有大约十几列和150行左右。在这两个条件下,我想遍历每一行并将其删除

  1. 第8列中的值未定义
  2. 第8列中定义的行ABOVE它的值。
  3. 我的代码看起来像这样,但它一直在崩溃。这是一个愚蠢的错误,但我无法弄明白。

    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列,无论哪种方式)

3 个答案:

答案 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, ]