我有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
我想概括一下这段代码。我经常将sapply
和apply
结合起来处理数据。但是,我想我从来没有将这些功能组合起来删除数据,我无法弄清楚如何去做。
下面的代码标识要删除的行,但不删除它们。以下代码的众多变化都没有奏效。
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
语句进行简单修改即可。虽然,也许完全不同的方法更好。
答案 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