2017-07-21 32 views
4

我需要按邏輯列(或者更準確地說,是否定)過濾表,但列的名稱可能會有所不同。這很容易,當我事先知道他們的名字:當列名存儲在字符串中時進行整齊評估

tb = tibble(
    id = 1:4, 
    col1 = c(TRUE, TRUE, FALSE, FALSE), 
    col2 = c(TRUE, FALSE, TRUE, FALSE) 
) 

tb 
## # A tibble: 4 x 3 
##  id col1 col2 
## <int> <lgl> <lgl> 
## 1  1 TRUE TRUE 
## 2  2 TRUE FALSE 
## 3  3 FALSE TRUE 
## 4  4 FALSE FALSE 

colname = quo(col1) 

tb %>% 
    filter(!!colname) # rows where col1 is true 
## # A tibble: 2 x 3 
##  id col1 col2 
## <int> <lgl> <lgl> 
## 1  1 TRUE TRUE 
## 2  2 TRUE FALSE 

tb %>% 
    filter(!(!!colname)) # rows where col1 is false 
## # A tibble: 2 x 3 
##  id col1 col2 
## <int> <lgl> <lgl> 
## 1  3 FALSE TRUE 
## 2  4 FALSE FALSE 

colname = quo(col2) 

tb %>% 
    filter(!!colname) # rows where col2 is true 
## # A tibble: 2 x 3 
##  id col1 col2 
## <int> <lgl> <lgl> 
## 1  1 TRUE TRUE 
## 2  3 FALSE TRUE 

tb %>% 
    filter(!(!!colname)) # rows where col2 is false 
## # A tibble: 2 x 3 
##  id col1 col2 
## <int> <lgl> <lgl> 
## 1  2 TRUE FALSE 
## 2  4 FALSE FALSE 

我不能,但是,弄清楚如何做同樣的當列名存儲在字符串。例如:

colname = "col1" 
tb %>% 
    filter(!!colname) 
## Error in filter_impl(.data, quo): Argument 2 filter condition does not evaluate to a logical vector 

colname = quo("col1") 
tb %>% 
    filter(!!colname) 
## Error in filter_impl(.data, quo): Argument 2 filter condition does not evaluate to a logical vector 

colname = quo(parse(text = "col1")) 
tb %>% 
    filter(!!colname) 
## Error in filter_impl(.data, quo): Argument 2 filter condition does not evaluate to a logical vector 

所以,問題是,我該怎麼做呢?

編輯:這不是this question的重複,因爲從那以後用dplyr做非標準評估的首選方式已經改變。所有以_結尾的函數現在都已棄用,現在推薦使用整齊的評估框架。

+0

[由(在dplyr)字符列名稱篩選數據幀(的可能的複製https://stackoverflow.com/questions/27197617/filter- data-frame-by-character-column-name-in-dplyr) – jdb

+1

@jdb這裏提供的所有解決方案都使用不推薦使用的函數,內部語義從此改變。 –

+0

[用dplyr使用字符串作爲輸入進行編程]的可能的副本(https://stackoverflow.com/questions/44121728/programming-with-dplyr-using-string-as-input) – aosmith

回答

5

我們可以使用從rlangsym用於評估串

library(rlang) 
library(dplyr) 
colname <- "col1" 

tb %>% 
    filter(!!sym(colname)) 
# A tibble: 2 x 3 
#  id col1 col2 
# <int> <lgl> <lgl> 
#1  1 TRUE TRUE 
#2  2 TRUE FALSE 
+1

正是我需要的,謝謝!我想這是一個非常常見的用例,不知道爲什麼在「Programming with dplyr」小插圖中沒有提到'sym'。 –