2017-07-23 40 views
0

用dplyr函數過濾,分組和變異數據的函數。基本的管道順序在函數外很好地工作,這就是我使用真正的列名的地方。把它放在一個函數中,列名是一個變量,一些函數可以工作,但有些函數並不是最顯着的dplyr :: filter()。例如:爲什麼dplyr filter()在函數內工作(即使用列名稱變量)?

var1 <- c('yes', NA, NA, 'yes', 'yes', NA, NA, NA, 'yes', NA, 'no', 'no', 'no', 'maybe', NA, 'maybe', 'maybe', 'maybe') 

var2 <- c(1:18) 

df <- data.frame(var1, var2) 

這工作正常(即過濾NA的):

df%>%filter(!is.na(var1)) 

...但是這並不:

x <- "var1" 

df%>%filter(!is.na(x)) 

...但這樣做:

df%>%select(x) 

這是NA的需要被特別過濾掉。

試圖獲取( 「X」),沒有好,和切片:

df[!is.na(x),] 

...沒有好,無論是。

有關如何傳遞變量以過濾函數內部(或外部)以及爲什麼變量與其他dplyr函數一起工作的任何想法?

回答

1

我們可以使用sym轉換爲符號,然後用UQ評價它

library(rlang) 
library(dplyr) 
df %>% 
    filter(!is.na(UQ(sym(x)))) 
#  var1 var2 
#1 yes 1 
#2 yes 4 
#3 yes 5 
#4 yes 9 
#5  no 11 
#6  no 12 
#7  no 13 
#8 maybe 14 
#9 maybe 16 
#10 maybe 17 
#11 maybe 18 
+0

爲什麼只有與過濾功能,而不是,例如,使用select()? –

+0

@ConnerM。 'select'同時帶有未加引號和帶引號的字符串,即'df%>%select('var1')''和'df%>%select(var1)'這不僅是'filter'。如果您想進行一些總結,那麼您必須執行相同的步驟 – akrun

+0

sym是否屬於特定的包? –

0

這也將工作,這是一個很簡單的 - 僅僅是指含有方括號中的列名變量並用它來指輸入DF(。):

> df %>% filter(!is.na((.)[x])) 
    var1 var2 
1 yes 1 
2 yes 4 
3 yes 5 
4 yes 9 
5  no 11 
6  no 12 
7  no 13 
8 maybe 14 
9 maybe 16 
10 maybe 17 
11 maybe 18 

注意,這也將在函數內部工作:

myfun <- function(df, var) { 
    df %>% filter(!is.na((.)[var])) 
} 

x <- "var1" 
myfun(df, x) 

    var1 var2 
1 yes 1 
2 yes 4 
3 yes 5 
4 yes 9 
5  no 11 
6  no 12 
7  no 13 
8 maybe 14 
9 maybe 16 
10 maybe 17 
11 maybe 18 
0

因爲我的名氣不夠高上面發表評論......我建議考慮看看我的答案在這裏:https://stackoverflow.com/a/45265617/6238025

如果你想與dplyr一個功能,你需要按照在此網頁上的說明:https://rpubs.com/hadley/dplyr-programming

library(tidyverse) 
var1 <- c('yes', NA, NA, 'yes', 
      'yes', NA, NA, NA, 'yes', NA, 'no', 
      'no', 'no', 'maybe', NA, 'maybe', 
      'maybe', 'maybe') 
var2 <- c(1:18) 

df <- data_frame(var1, var2) 

your_function <- function(df, filter) { 
     # Make filter a quosure 
     filter = enquo(filter) 

     df %>% 
     filter(!is.na(!!filter)) -> new_df 

     return(new_df) 
} 
new_df <- your_function(df = df, filter = var1) 

你也可以跳過函數內filter = enquo(filter),然後你的電話是:

your_function(df=df, filter=quo(var1))

然而,第一種方法是使函數調用更好。你不需要記住quo()

這應該工作!

1

有一個新的包seplyr,通過標準的評估標準dplyr。試一試。您可以將正常的引用代碼傳遞給dplyr。它使傳遞參數和函數在dplyr中更容易。

對於您的情況:

install.packages("seplyr") 
library(seplyr) 
x<-"var1" 
df%>%filter_se(paste0("!is.na(", x , ")")) 
相關問題