在R survey包的svyby中为svymean设置自定义置信水平
如何在
svyby中调用svymean并设置自定义置信区间水平? 我使用R的survey和tidyverse包,基于mtcars数据集编写代码,按组计算多个变量的加权均值及置信区间。原有代码可正常生成默认95%置信区间,但尝试将置信区间改为0.99时出现错误。
原正常代码
library(survey) library(tidyverse) var_list = c("wt","qsec") svy_design <- svydesign( ids = ~1, data = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit(), weights = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit() |> select(mpg) ) lapply(var_list, function( x ) svyby(as.formula( paste0( "~" , x ) ) , by = ~cyl, design = svy_design, FUN = svymean, keep.names = FALSE, vartype = "ci")) %>% bind_rows() |> relocate(wt, .after = last_col()) %>% pivot_longer(!c(cyl,ci_l,ci_u),names_to = "var",values_to = "mean",values_drop_na = TRUE)
错误代码及报错信息
错误代码中尝试直接传递FUN = svymean(level = 0.99),触发如下报错:
Error in svymean(level = 0.99) : argument "design" is missing, with no default
问题原因
错误的核心是不能直接在FUN参数中调用带参数的svymean——这样会立即执行svymean函数,但此时缺少design等必要参数,导致报错。正确的做法是将svymean的附加参数(如level)直接作为svyby的额外参数传递,或者用匿名函数包装svymean并指定参数。
正确解决方案
方法1:直接在svyby中传递level参数
svyby支持将FUN所需的额外参数直接作为自身的参数传入,无需修改FUN的写法:
library(survey) library(tidyverse) var_list = c("wt","qsec") svy_design <- svydesign( ids = ~1, data = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit(), weights = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit() |> select(mpg) ) lapply(var_list, function( x ) svyby(as.formula( paste0( "~" , x ) ) , by = ~cyl, design = svy_design, FUN = svymean, keep.names = FALSE, vartype = "ci", level = 0.99)) %>% # 直接添加level参数指定置信水平 bind_rows() |> relocate(wt, .after = last_col()) %>% pivot_longer(!c(cyl,ci_l,ci_u),names_to = "var",values_to = "mean",values_drop_na = TRUE)
方法2:用匿名函数包装svymean
如果需要更灵活的参数控制,可以用匿名函数包裹svymean,明确指定参数:
library(survey) library(tidyverse) var_list = c("wt","qsec") svy_design <- svydesign( ids = ~1, data = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit(), weights = mtcars |> dplyr::select(cyl,all_of(var_list),mpg) |> na.omit() |> select(mpg) ) lapply(var_list, function( x ) svyby(as.formula( paste0( "~" , x ) ) , by = ~cyl, design = svy_design, FUN = function(formula, design) svymean(formula, design, level = 0.99), # 匿名函数包装并指定level keep.names = FALSE, vartype = "ci")) %>% bind_rows() |> relocate(wt, .after = last_col()) %>% pivot_longer(!c(cyl,ci_l,ci_u),names_to = "var",values_to = "mean",values_drop_na = TRUE)
内容的提问来源于stack exchange,提问作者flâneur
相关产品推荐
相关产品推荐

