根据包含列名称的输入向量过滤数据框

时间:2018-08-31 08:23:05

标签: r dplyr data-manipulation

我的数据框如下

Sol_name    geo_pos     loc_pos     dol_pos    pol_pos   kol_pos

A            1            1          0          0         1
B            0            1          1          0         0
C            1            0          1          1         1
D            0            1          0          0         1

我需要创建一个函数,用户可以在其中将列名称输入向量中,并且其中任何列中的值为1时,数据帧都会被过滤

示例:如果输入为col_nm = c("geo_pos","dol_pos"),那么我正在寻找的输出为

Sol_name    geo_pos     loc_pos     dol_pos    pol_pos   kol_pos

A            1            1          0          0         1
B            0            1          1          0         0
C            1            0          1          1         1

有什么有效的方法吗?

数据

df <- read.table(text="Sol_name    geo_pos     loc_pos     dol_pos    pol_pos   kol_pos
A            1            1          0          0         1
B            0            1          1          0         0
C            1            0          1          1         1
D            0            1          0          0         1",h=T)

5 个答案:

答案 0 :(得分:4)

在这里,我们可以有效地使用rowSums来过滤所选列中至少有一个“ 1”的行。

get_one_rows <- function(cols) {
    df[rowSums(df[cols] == 1) > 0, ]
}

col_nm = c("geo_pos","dol_pos")
get_one_rows(col_nm)

# Sol_name geo_pos loc_pos dol_pos pol_pos kol_pos
#1        A       1       1       0       0       1
#2        B       0       1       1       0       0
#3        C       1       0       1       1       1


col_nm = c("kol_pos")
get_one_rows(col_nm)

#  Sol_name geo_pos loc_pos dol_pos pol_pos kol_pos
#1        A       1       1       0       0       1
#3        C       1       0       1       1       1
#4        D       0       1       0       0       1

答案 1 :(得分:2)

使用tidverse:

df %>% filter_at(col_nm,any_vars(.==1))

#  Sol_name geo_pos loc_pos dol_pos pol_pos kol_pos
#1        A       1       1       0       0       1
#2        B       0       1       1       0       0
#3        C       1       0       1       1       1

答案 2 :(得分:0)

使用plyr

library(plyr)
unique(ldply(col_nm,.fun = function(x){(df[df[x]==1,])}))

输出:

     Sol_name geo_pos loc_pos dol_pos pol_pos kol_pos
1        A       1       1       0       0       1
2        C       1       0       1       1       1
3        B       0       1       1       0       0

OR

unique(as.data.frame(do.call(rbind, lapply(col_nm, function(x) df[df[x]==1,]))))

答案 3 :(得分:0)

带有base R的{​​{1}}选项

Reduce

答案 4 :(得分:0)

您可以使用pmax

df[as.logical(do.call(pmax,df[col_nm])),]

#   Sol_name geo_pos loc_pos dol_pos pol_pos kol_pos
# 1        A       1       1       0       0       1
# 2        B       0       1       1       0       0
# 3        C       1       0       1       1       1