如何编写一个使用扫帚,dplyr和lm的函数?

时间:2017-08-24 13:00:20

标签: r dplyr broom

考虑这个非常简单的例子

library(dplyr)
library(broom)

dataframe <- data_frame(id = c(1,2,3,4,5,6),
                        group = c(1,1,1,2,2,2),
                        value = c(200,400,120,300,100,100))

# A tibble: 6 x 3
     id group value
  <dbl> <dbl> <dbl>
1     1     1   200
2     2     1   400
3     3     1   120
4     4     2   300
5     5     2   100
6     6     2   100

这里我想编写一个函数,输出value均值的置信估计的上限。也就是说,

get_ci_high <- function(data, myvar){
  confint_tidy(lm(data = data, myvar ~ 1)) %>% pull(conf.high)
}

现在,这很容易实现

confint_tidy(lm(data = dataframe, value ~ 1)) %>% pull(conf.high)
[1] 332.9999

这也有效(请注意group_by后的电话)

dataframe %>% group_by(group) %>% mutate(dealwithit = get_ci_high(., value))
# A tibble: 6 x 4
# Groups:   group [2]
     id group value dealwithit
  <dbl> <dbl> <dbl>      <dbl>
1     1     1   200   598.2674
2     2     1   400   598.2674
3     3     1   120   598.2674
4     4     2   300   453.5102
5     5     2   100   453.5102
6     6     2   100   453.5102

这非常有效

mindblow <- function(data, groupvar, outputvar){
  quo_groupvar <- enquo(groupvar)
  quo_outputvar <- enquo(outputvar)

  data %>% group_by(!!quo_groupvar) %>% 
    summarize(output =  get_ci_high(., !!quo_outputvar))%>% 
    ungroup()

}

> mindblow(dataframe, groupvar = group, outputvar = value)
# A tibble: 2 x 2
  group   output
  <dbl>    <dbl>
1     1 598.2674
2     2 453.5102

...但失败

get_ci_high(dataframe, value)
 Error in eval(expr, envir, enclos) : object 'value' not found 

我不知道这里有什么问题。我真的需要一个适用于上述四种情况的解决方案。

有什么想法吗? 非常感谢!!

1 个答案:

答案 0 :(得分:2)

原因是当您传递value参数时,您希望R在公式中使用其名称 "value",而不是变量的值(不存在)。

一种解决方案是使用substitute()non-standard evaluation)提取名称,并使用as.formula创建公式:

get_ci_high <- function(data, myvar) {
  col_name <- as.character(substitute(myvar))
  fmla <- as.formula(paste(col_name, "~ 1"))

  confint_tidy(lm(data = data, fmla)) %>% pull(conf.high)
}

get_ci_high(dataframe, value)

但是,我强烈建议将公式 value ~ 1作为第二个参数传递。这对于执行其他线性模型(当您还有预测变量时)更简单,更灵活。

get_ci_high <- function(data, fmla) {      
  confint_tidy(lm(data = data, fmla)) %>% pull(conf.high)
}

get_ci_high(dataframe, value ~ 1)