根据R

时间:2018-02-27 16:40:38

标签: r data.table apply

我有一个数据框,其中有多个列(超过30个)保存在列表中。我想对所有这些列应用相同的标准,而不为每列编写每个代码。我有下面的例子来帮助更好地理解我的问题

A<-c("A","B","C","D","E","F","G","H","I")
B<-c(0,0,0,1,2,3,0,0,0)
C<-c(0,1,0,0,1,2,0,0,0)
D<-c(0,0,0,0,1,1,0,1,0)
E<-c(0,0,0,0,0,0,0,1,0)
data<-data.frame(A,B,C,D,E)

假设我以上面的df为例,我已经保存了cols列表,如下所示

list <- c("B","C","D","E")

我想使用与以下标准相同的那些cols

setDT(data)[B>=1 | C>=1 | D>=1 | E>=1]

获得以下结果

   A B C D E
1: B 0 1 0 0
2: D 1 0 0 0
3: E 2 1 1 0
4: F 3 2 1 0
5: H 0 0 1 1

但是,有没有办法在不编写每个单独的列标准的情况下得到上述答案(例如B> = 1 | C&gt; = 1 ....),因为我在实际数据中有超过30个cols。非常感谢

4 个答案:

答案 0 :(得分:5)

对于检查行中至少有一个值是否至少为1的具体示例,您可以使用rowSums

data[rowSums(data[,-1]) > 0, ]
#   A B C D E
# 2 B 0 1 0 0
# 4 D 1 0 0 0 
# 5 E 2 1 1 0
# 6 F 3 2 1 0
# 8 H 0 0 1 1

如果您还有其他标准,也可以考虑在any

中使用apply
ind <- apply(data[,-1], 1, function(x) {any(x >= 1)})
data[ind,]
#   A B C D E
# 2 B 0 1 0 0
# 4 D 1 0 0 0 
# 5 E 2 1 1 0
# 6 F 3 2 1 0
# 8 H 0 0 1 1

答案 1 :(得分:4)

dplyr::filter_at会做到这一点。

library(dplyr)
data %>% filter_at(vars(-A),any_vars(.>=1))
#   A B C D E
# 1 B 0 1 0 0
# 2 D 1 0 0 0
# 3 E 2 1 1 0
# 4 F 3 2 1 0
# 5 H 0 0 1 1

答案 2 :(得分:2)

你总是可以使用Reduce,这很好,因为你可以把你想要的任何类型的逻辑放到函数中:

一个简单的方法可能是:

data[Reduce("|", as.data.frame(data[,list] >= 1)),]
#  A B C D E
#2 B 0 1 0 0
#4 D 1 0 0 0
#5 E 2 1 1 0
#6 F 3 2 1 0
#8 H 0 0 1 1

一点解释:Reduce先后将相同的函数应用于x的每个元素。在这种情况下,“|”运算符应用于data.frame

的每个逻辑列

如果您想进行更复杂的逻辑检查,可以使用自己的匿名函数来完成。

答案 3 :(得分:-1)

请使用R。

中的apply进行检查
B<-c(0,0,0,1,2,3,0,0,0)
C<-c(0,1,0,0,1,2,0,0,0)
D<-c(0,0,0,0,1,1,0,1,0)
ef=data.frame(B,C,D)
con=apply(ef,2,function(x) x>1 )