2015-10-04 66 views
0

我一直在努力解決這個問題,它與a question raised here before非常相似。不知何故,我無法將這個問題給出的解決方案轉化爲我自己的問題。在另一個函數中使用dplyr函數

我剛開始時製作的示例數據幀:

test.df <- data.frame(col1 = rep(c('a','b'), each=5), col2 = runif(10)) 
str(test.df) 

下面的函數應該創建基於「組變量」的基團的「statvar」的平均新的數據幀。

test.f <- function(df, groupvar, statvar) { 
    df %>% 
    group_by_(groupvar) %>% 
    select_(statvar) %>% 
    summarise_(
     avg = ~mean(statvar, na.rm = TRUE) 
    ) 
} 

test.f(df = test.df, 
     groupvar = "col1", 
     statvar = "col2") 

我想什麼這個返回是用2個計算的平均值(一個用於在COL1所有一個值,一個用於在COL1所有的b值)的數據幀。相反,我得到這個:

col1 avg 
1 a NA 
2 b NA 
Warning messages: 
1: In mean.default("col2", na.rm = TRUE) : 
    argument is not numeric or logical: returning NA 
2: In mean.default("col2", na.rm = TRUE) : 
    argument is not numeric or logical: returning NA 

我發現這種奇怪的,因爲我敢肯定COL2是數字:

str(test.df) 
'data.frame': 10 obs. of 2 variables: 
$ col1: Factor w/ 2 levels "a","b": 1 1 1 1 1 2 2 2 2 2 
$ col2: num 0.4269 0.1928 0.7766 0.0865 0.1798 ... 

回答

3
library(lazyeval) 
library(dplyr) 

test.f <- function(df, groupvar, statvar) { 
    test.df %>% 
    group_by_(groupvar) %>% 
    select_(statvar) %>% 
    summarise_(
     avg = (~mean(statvar, na.rm = TRUE)) %>% 
     interp(statvar = as.name(statvar)) 
    ) 
} 

test.f(df = test.df, 
     groupvar = "col1", 
     statvar = "col2") 

您的問題是,「COL2」正在取代statvar,和mean("col2")未定義

+0

這很好,非常感謝。所以interp()基本上說「R,你應該看到這是一個變量,而不是一個字符串」?然而,我仍然有點困惑,爲什麼avg通過管道符號%>%連接到interp()。 – 1053Inator

+0

@ 1053Inator,你可以把它寫成'avg = interp(〜mean(statvar,na.rm = TRUE),statvar = as.name(statvar))''不用管道系統 –

+1

interp採用expresion'〜mean(statvar,na .rm = TRUE)',並且每次看到statvar字時都會替換as.name(statvar)的結果,即col2。所以表達式被轉換爲「〜mean(col2,na.rm = TRUE)' – bramtayl

0

隨着即將發佈dplyr 0.6.0,新功能可以幫助。新功能是UQ(),它引用了引用的內容。您輸入statvar作爲字符串,如"col1"。 dplyr具有可以定期評估的備用功能,如group_by_select_。但是對於summarise_,字符串的更改可能會像上面的答案那樣難看。我們現在可以使用常規的summarise函數並取消引用的變量名稱。有關'引用引用'的含義的更多幫助,請參閱see this vignette。現在有the developer's version了。

library(dplyr) 
test.df <- data.frame(col1 = rep(c('a','b'), each=5), col2 = runif(10)) 
test.f <- function(df, groupvar, statvar) { 
    q_statvar <- as.name(statvar) 
    df %>% 
    group_by_(groupvar) %>% 
    select_(statvar) %>% 
    summarise(
     avg = mean(!!q_statvar, na.rm = TRUE) 
    ) 
} 

test.f(df = test.df, 
     groupvar = "col1", 
     statvar = "col2") 
# # A tibble: 2 × 2 
#  col1  avg 
# <fctr>  <dbl> 
# 1  a 0.6473072 
# 2  b 0.4282954 
相關問題