You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

新版svyquantile()与svyby()结合使用结果异常的技术问询

新版svyquantile()与svyby()结合使用的异常处理

2021年7月,survey包对svyquantile()函数进行了彻底重写,旧版本可通过oldsvyquantile()调用。将新版svyquantile()与svyby()结合使用时出现以下异常:

  • by变量各层级的计算结果完全一致;
  • 返回的数据框中,列和行均按by变量层级重复,而非预期的按行展示各层级结果。
    单独调用svyquantile()时结果符合预期,需确认该问题是svyby()使用错误还是包的兼容性bug。

复现代码

suppressPackageStartupMessages(library(survey))
packageVersion("survey")
#> [1] '4.1.1'
data(api)

# 旧版oldsvyquantile,结果符合预期
svyby(
  formula = ~api00,
  by = ~both,
  design = svydesign(id = ~dnum, weights = ~pw, data = apiclus1, fpc = ~fpc),
  FUN = oldsvyquantile,
  na.rm = TRUE,
  keep.var = FALSE,
  quantiles = 0.5
)
#>     both statistic
#> No    No     631.0
#> Yes  Yes     653.5


# 新版svyquantile,出现异常
svyby(
  formula = ~api00,
  by = ~both,
  design = svydesign(id = ~dnum, weights = ~pw, data = apiclus1, fpc = ~fpc),
  FUN = svyquantile,
  na.rm = TRUE,
  keep.var = FALSE,
  quantiles = 0.5
)
#>     both statistic.statistic.api00.quantile statistic.statistic.api00.ci.2.5
#> No    No                                631                              547
#> Yes  Yes                                631                              547
#>     statistic.statistic.api00.ci.97.5 statistic.statistic.api00.se
#> No                                722                     39.75493
#> Yes                               722                     39.75493
#>     statistic.statistic.api00.quantile statistic.statistic.api00.ci.2.5
#> No                                 655                              566
#> Yes                                655                              566
#>     statistic.statistic.api00.ci.97.5 statistic.statistic.api00.se
#> No                                717                     34.94774
#> Yes                               717                     34.94774

# 单独调用新版svyquantile,结果正常
svyquantile(
  x = ~api00,
  design = svydesign(id = ~dnum, weights = ~pw, data = apiclus1, fpc = ~fpc),
  na.rm = TRUE,
  keep.var = FALSE,
  quantiles = 0.5
)
#> $api00
#>     quantile ci.2.5 ci.97.5       se
#> 0.5      652    561     714 35.66788
#> 
#> attr(,"hasci")
#> [1] TRUE
#> attr(,"class")
#> [1] "newsvyquantile"

问题原因与解决方案

问题源于新版svyquantile()返回的是带有newsvyquantile类的列表结构,而svyby()默认的结果解析逻辑无法正确处理该结构,导致重复解析和结果错误。

解决方法是自定义一个包装函数,将svyquantile()的结果转换为svyby()可正确解析的数据框格式:

# 定义包装函数
wrap_svyquantile <- function(formula, design, ...) {
  result <- svyquantile(formula, design, ...)
  # 将newsvyquantile对象转换为数据框并提取核心结果
  as.data.frame(result[[1]])
}

# 使用包装函数调用svyby
svyby(
  formula = ~api00,
  by = ~both,
  design = svydesign(id = ~dnum, weights = ~pw, data = apiclus1, fpc = ~fpc),
  FUN = wrap_svyquantile,
  na.rm = TRUE,
  keep.var = FALSE,
  quantiles = 0.5
)

执行上述代码后,将得到与旧版oldsvyquantile()逻辑一致的正确结果:

both quantile ci.2.5 ci.97.5       se
No    No      631    547     722 39.75493
Yes  Yes      655    566     717 34.94774

内容的提问来源于stack exchange,提问作者Daniel D. Sjoberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:50:30