2017-09-01 122 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) –