如何编写使用 broom、dplyr 和 lm 的函数?
how to write a function that uses broom, dplyr and lm?
考虑这个非常简单的例子
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
我不明白这里有什么问题。我真的需要一个适用于上述四种情况的解决方案。
有什么想法吗?
非常感谢!!
原因是当你传递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)
考虑这个非常简单的例子
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
我不明白这里有什么问题。我真的需要一个适用于上述四种情况的解决方案。
有什么想法吗? 非常感谢!!
原因是当你传递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)