使用apply删除行

时间:2014-04-08 18:17:59

标签: r apply sapply

我有data.frame并希望删除符合某些复杂条件的行。我可以使用如下重复的一系列行来完成。但是,这种方法并不普遍。

my.df <- read.table(text = '
  Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9
    0    1    0    1    1    1    0    0    0
    1    0    1    1    1    1    0    0    1
    0    1    1    0    1    1    0    0    1
    0    1    1    1    1    1    1    1    1
    1    0    1    0    1    1    0    1    1
    0    0    1    0    0    0    1    0    1
    0    0    1    0    0    0    0    0    0
    1    0    1    0    1    1    1    0    0
    1    1    1    1    0    0    1    0    1
    0    1    0    0    0    0    0    0    1
    0    0    1    1    1    0    1    0    1
    1    0    0    0    1    0    0    0    1
    1    0    1    1    0    0    0    1    0
    0    0    1    1    0    0    1    1    1
    1    0    0    0    1    0    0    1    0
    0    0    0    0    0    1    0    1    1
    1    1    0    0    1    1    1    1    1
    0    0    1    0    0    0    0    1    0
    0    0    1    1    1    0    1    0    0
    0    1    0    0    1    1    1    0    0
', header = TRUE)

desired.result <- read.table(text = '
  Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9
    0    0    1    0    0    0    0    0    0
    1    1    1    1    0    0    1    0    1
    1    0    1    1    0    0    0    1    0
    0    0    1    0    0    0    0    1    0
', header = TRUE)

# this works, but is not general

my.df2 <- my.df
my.df2 <- my.df2[!(my.df2[,1]==0 & (my.df2[,4]==1 | my.df2[,5]==1)),]
my.df2 <- my.df2[!(my.df2[,2]==0 & (my.df2[,6]==1 | my.df2[,7]==1)),]
my.df2 <- my.df2[!(my.df2[,3]==0 & (my.df2[,8]==1 | my.df2[,9]==1)),]
my.df2

row.names(my.df2) <- NULL
all.equal(my.df2, desired.result)
# [1] TRUE

我想概括一下这段代码。我经常将sapplyapply结合起来处理数据。但是,我想我从来没有将这些功能组合起来删除数据,我无法弄清楚如何去做。

下面的代码标识要删除的行,但不删除它们。以下代码的众多变化都没有奏效。

my.df3 <- as.matrix(my.df)

sapply(seq_along(1:3), function(i) {
       apply(my.df3, 1, function(j) { 
            !(j[i]==0 & (j[(i+1)*2]==1 | j[((i+1)*2+1)]==1)) 
       }) 
})

我找不到在互联网上搜索“使用apply删除行”的解决方案。谢谢你的任何建议。我更喜欢基础R中的解决方案。我怀疑只需要对sapply语句进行简单修改即可。虽然,也许完全不同的方法更好。

2 个答案:

答案 0 :(得分:1)

首先,seq_along(1:3)是多余的,因为该函数只会返回1:3。其次,如果apply(..., 1, ...)调用的结果是逻辑向量,则可以使用它进行子集化:

my.df3[apply(my.df3, 1, ...,), ]

答案 1 :(得分:0)

这是一个基于组合变体的功能性解决方案,在发布之前与Robert Krzyzanowski建议在apply内嵌套my.df3

my.df3 <- as.matrix(my.df)

my.test <- sapply(seq_along(1:3), function(i) {
                  apply(my.df3, 1, function(j) { 
                       !(j[i]==0 & (j[(i+1)*2]==1 | j[((i+1)*2+1)]==1)) 
                  })
}) 

my.df3[apply(my.test,1,function(i) {all(i)==TRUE}),]

     Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9
[1,]    0    0    1    0    0    0    0    0    0
[2,]    1    1    1    1    0    0    1    0    1
[3,]    1    0    1    1    0    0    0    1    0
[4,]    0    0    1    0    0    0    0    1    0