删除数据框中具有特定值的行,该行在另一个数据框的相应行中

时间:2017-05-08 15:46:17

标签: r dataframe rows indicator grepl

我有两个数据框。

第一个保存我的实际数据,我们称之为数据。第二个用作指示符矩阵,使用if-else语句构造,该语句检查包含至少1或2的值的行的出现,将其称为 indic

以下是一个例子:

col1<-c(1,3,1,3,2)
col2<-c(3,4,2,3,"")
col3<-c(1,3,"","","")
col4<-c(2,"","","","")

data<-data.frame(cbind(col1,col2,col3,col4))

> data
  col1 col2 col3 col4
     1    3    1    2
     3    4    3     
     1    2          
     3    3          
     2   

数据的行必须包含至少1或2 ,所以这是我的函数:

remove<-function(x){

  if (((x[1] == "1") | (x[1] == "2")) | ((x[2] == "1") | (x[2] == "2"))
      | ((x[3] == "1") | (x[3] == "2")) | ((x[4] == "1") | (x[4] == "2"))){
    return(0)
  }

else{
  return(1)
}
}

indic<-data.frame(apply(data,1,remove))

> indic
        y
1       0
2       1
3       0
4       1
5       0

通过查看数据,第2行和第4行不包含至少1或2,由 indic 确认。

我想删除数据中的第2行和第4行,它们对应于数据中的第2行和第4行。我已经尝试了以下内容:

finalMatrix<-class(array)

for(i in 1:nrow(indic)){
  if (indic[i,1] == "1"){
    finalMatrix = data[-i,]
  }
  else{
    data[i,] = data[i,]
  }
}

但是,我的输出是这样的:

> finalMatrix
  col1 col2 col3 col4
    1    3    1    2
    3    4    3     
    1    2                  
    2    

这有效地消除了第四行。我认为这可能与我必须在每次迭代后创建一个新数据帧这一事实有关,但问题是迭代长度会发生变化。

想知道我的代码是否在正确的轨道上...任何建议都很可爱。我一直在思考这个问题。

-Soph

1 个答案:

答案 0 :(得分:1)

你可以尝试生成一个TRUE / FALSE vetor而不是你的指示向量,它包含0/1。这使得最终过滤更加明显。

> data
  col1 col2 col3 col4
1    1    3    1    2
2    3    4    3     
3    1    2          
4    3    3          
5    2        

使用any可让您轻松访问12行的内容。如果符合这两个条件中的一个,第二个any会告诉您。如果第二个参数设置为1,则apply()将遍历所有行。

indic <- apply(data, 1, function(row) {
    any(c(any(row == 1), any(row == 2)))
})


> indic
[1]  TRUE FALSE  TRUE FALSE  TRUE

> data[indic,]
  col1 col2 col3 col4
1    1    3    1    2
3    1    2          
5    2   

正如您的问题标题所示,指示矢量也可以应用于另一个数据框,但重要的是要注意具有相同尺寸或​​旨在进行矢量回收的数据框和指示矢量。

挑选@ nicola建议使用矢量化。

data[rowSums(data=="1" | data=="2")>0,]

这样可以最有效地节省循环并创建indic。虽然从rowSums(data=="1" | data=="2")>0发出的TRUE / FALSE向量仍然可以保存在变量中。