在另一个函数中使用dplyr函数

时间:2015-10-04 09:12:03

标签: r dplyr

我一直在努力解决这个与a question raised here before非常相似的问题。不知何故,我无法将该问题中给出的解决方案转化为我自己的问题。

我从制作示例数据框开始:

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

以下函数应根据“groupvar”的组创建一个具有“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 ...

2 个答案:

答案 0 :(得分:4)

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")

你的问题是&#34; col2&#34;正在替换statvar,mean("col2")未定义

答案 1 :(得分: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