2016-10-26 56 views
1

我有一個自定義過濾器的列表,我需要通過我的數據框子集。例如,對於mtcars我有這個名單:R:如何將一個過濾器列表傳遞給一個函數

filters=c(mpg>15, wt<2, carb>2 & am==0) 

我想傳遞的列表中fmean後,這個列表傳遞給函數包含dplyr /管

fmean <- function(filter_x) mtcars %>% filter(filter_x) %>% summarise(mean(disp)) 

我的預期成果是:

subset    mean(disp) 
mpg>15     192 
wt<2     80.2 
carb>2 & am==0   324 

如何獲取上述輸出?

編輯:找到一個解決方案tidyverse由於@alistaire,和其他人誰回答這裏:

library(tidyverse) 
filters <- c("mpg > 15", "wt < 2", "carb > 2 & am==0") 

fmean <- function(filter_x) { mtcars %>% 
            filter_(filter_x) %>% 
            summarise(mean(disp)) %>% 
            mutate(subset=filter_x) %>% 
            select(subset, everything()) } 
filters %>% map_df(fmean) 

輸出:

subset    mean(disp) 
mpg>15     192.3 
wt<2     80.2 
carb>2 & am==0   324.5 

回答

1

data.table方式,eval(parse())

library(data.table) 
mt_dt <- data.table(mtcars) 

filters <- c("mpg > 15", "wt < 2", "carb > 2 & am==0") 

out <- sapply(filters, function(x){mt_dt[eval(parse(text = x)), mean(disp)]}) 
out 
# mpg > 15   wt < 2  carb > 2 & am==0 
# 192.3115   80.2250    324.4600 

我們遍歷我們的過濾器,併爲大家子集,每個過濾器適用於我們的聚合功能

這會產生一個命名的向量,該向量相當靈活。如果你喜歡一個表,你可以使用:

data.table(subset = names(out), `mean(disp)` = out) 
#    subset mean(disp) 
# 1:   mpg > 15 192.3115 
# 2:   wt < 2 80.2250 
# 3: carb > 2 & am==0 324.4600 
+0

不應該將它轉置爲獲得所需的輸出嗎? – Irakli

+0

@Irakli我可能會更喜歡使用一個命名的向量,但編輯將轉換包括到表中。 – Chris

4

最直接的方式來完成這可能是使用purrr該包裝與dplyr一起是tidyverse包裝的一部分:

library(tidyverse) 

filters <- c("mpg > 15", "wt < 2", "carb > 2 & am==0") 

fmean <- function(filter_x) { 
    # Create list of means 
    means <- filter_x %>% 
    map(~ mtcars %>% filter_(.dots = .x) %>% summarise(mean(disp))) 

    # Create tibble from means 
    tibble(subset = filter_x, means = unlist(means)) 
} 

fmean(filters) 

另外,您希望使用filter_而不是filter,它允許您將子集條件作爲字符串傳遞,而不是作爲未加引號的文本傳遞。

+0

我很驚訝與tidyverse的解決方案比使用data.table – Irakli

+0

data.table肯定可以打高爾夫的代碼與他們最好的一個班輪更復雜:) –

+0

編輯爲高爾夫樂趣^ _^ –

1

在基礎R:

fmean <- function(filter_x) data.frame(
    subset=filter_x, 
    do.call(rbind, 
      lapply(filter_x, function(x) 
      mtcars %>% filter_(x) %>% summarise(mean(disp))))) 

fmean(filters) 
      subset mean.disp. 
1   mpg > 15 192.3115 
2   wt < 2 80.2250 
3 carb > 2 & am==0 324.4600 
相關問題