2017-09-01 59 views
1

我已经与消费者建立了一个数据库,每一列都是他们见面的条件。我要选择,所以我对循环做只有符合每个条件的基地,但过滤功能似乎不起作用,并且在每一个基地,我得到0的结果,事件你我知道我应该得到的东西:在`dplyr`过滤器中使用变量

database <- data.frame(ID = 1:10, Con1 = c(1,1,0,1,0,0,0,1,0,1), Con2 = c(1,0,0,0,0,0,0,0,0,0)) 
varibles <- names(database)[2:3] 

for(i in 1:length(varibles)){ 
    tmp <- database %>% 
    filter_(varibles[i] == 1) 
} 

我读,我应该使用过滤器,“_”,但它没有作用(Use variable names in functions of `dplyr`

我解决了这个问题不使用dplyr:

tmp <- database 
    tmp <- tmp[tmp[, varibles[i]] == 1, ] 

回答

1

也许,我们并不需要一个循环,使用filter_at

如果我们需要具有任一“CON”值的filter行是1,则我们使用any_vars引用一个谓词表达式应适用于在我们使用索引.predicate(这里提到的变量。如果我们需要的字符串名称,然后用vars(matches("Con"))

database %>% 
    filter_at(2:3, any_vars(.==1)) 

假设把它包起来,如果我们需要有1两列,使用all_vars

database %>% 
    filter_at(2:3, all_vars(.==1)) 

对于多个数据集,发起list和从每次迭代的输出存储在其内部

tmp <- setNames(vector("list", length(varibles)), varibles) 
for(i in seq_along(varibles)){ 
    tmp[[i]] <- database %>% 
       filter_at(vars(varibles[i]), all_vars(. == 1)) 
} 

或用symrlang

tmp <- setNames(vector("list", length(varibles)), varibles) 
for(i in seq_along(varibles)){ 
    tmp[[i]] <- database %>% 
      filter(UQ(rlang::sym(varibles[i])) == 1) 
} 

tmp 
#$Con1 
# ID Con1 Con2 
#1 1 1 1 
#2 2 1 0 
#3 4 1 0 
#4 8 1 0 
#5 10 1 0 

#$Con2 
# ID Con1 Con2 
#1 1 1 1 

以上方法使用R 3.4.1dplyr_0.7.2做。由于OP在R升级到新版本中提到了一些困难,我们尝试了get方式使用R 3.1.3dplyr_0.4.3

tmp <- setNames(vector("list", length(varibles)), varibles) 
for(i in seq_along(varibles)){ 
    tmp[[i]] <- database %>% 
        filter(get(varibles[i], envir = as.environment(.))==1) 
} 

tmp 
#$Con1 
# ID Con1 Con2 
#1 1 1 1 
#2 2 1 0 
#3 4 1 0 
#4 8 1 0 
#5 10 1 0 

#$Con2 
# ID Con1 Con2 
#1 1 1 1 
+0

不,我需要在以后获得独立datafremes每个条件,因为我对他们的工作,并上传到服务器 –

+0

@MariuszSiatka没问题,更新了帖子 – akrun

+0

我试过使用你的代码,但它不起作用。 filter_at的方法会产生错误:“function_list [[k]](value)中的错误:无法找到函数”filter_at“”并且它在我没有改变的情况下复制你的代码时也会出现。我不能也使用“过滤器(UQ(rlang :: sym(varibles [i]))== 1)”,因为我有旧的R和'rlang'包不可用(对于R版本3.3.1) –