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

summarytools中freq()排除NA后转data.frame异常的解决方法咨询

解决summarytools::freq()设置report.nas=FALSE后转data.frame仍包含缺失值的问题

问题说明

使用summarytools包的freq()函数时,设置report.nas = FALSE可以在打印时排除缺失值,但将结果转为data.frame后,缺失值行被重新包含,总观测数仍为原始样本量(而非排除NA后的数量)。

复现代码

# 创建包含缺失值的smoker向量
smoker <- c("yes", "no", "yes", NA, NA, NA, "yes", "no", "yes", "no")
df <- data.frame(smoker)

library(summarytools)
library(dplyr)

# 生成排除缺失值的频率表(打印时正确)
freq(df$smoker, report.nas = FALSE)

# 转为data.frame后出现问题
table <- as.data.frame(freq(df$smoker, report.nas = FALSE))
# 或用dplyr管道
table <- df %>% freq(smoker, report.nas = FALSE) %>% as.data.frame()
table

预期与实际结果差异

  • 预期:仅保留有效观测(n=7),无缺失值行
  • 实际:缺失值行<NA>被保留,总观测数为原始的10

原因分析

freq()函数生成的对象内部存储了完整的统计数据(包括缺失值相关的统计),report.nas = FALSE仅控制打印输出时隐藏缺失值行,而as.data.frame.freq方法默认会提取所有统计字段,因此转成data.frame后会恢复缺失值行和原始总样本量。

解决方案

方法1:使用getSummary()提取显示用表格

freq对象的summary属性就是report.nas = FALSE时显示的内容,直接用getSummary()提取即可得到符合预期的data.frame:

freq_obj <- freq(df$smoker, report.nas = FALSE)
table <- getSummary(freq_obj)
table

输出结果:

Freq        %   % Cum.
     no      3    42.86    42.86
    yes      4    57.14   100.00
  Total      7   100.00   100.00

方法2:手动过滤已生成的data.frame

如果已经得到包含缺失值的data.frame,可手动筛选行并修正Total统计:

table <- as.data.frame(freq(df$smoker, report.nas = FALSE))

filtered_table <- table %>%
  # 移除缺失值行和原始Total行
  filter(!rownames(.) %in% c("<NA>", "Total")) %>%
  # 添加修正后的Total行
  bind_rows(
    data.frame(
      Freq = sum(.$Freq),
      `% Valid` = 100,
      `% Valid Cum.` = 100,
      `% Total` = 100,
      `% Total Cum.` = 100,
      row.names = "Total"
    )
  )

filtered_table

循环生成频率表并应用kable样式

针对多变量循环处理,并结合knitr::kable生成格式化表格:

library(knitr)

# 扩展数据框,添加另一个分类变量
df$drinker <- c("yes", "no", NA, "yes", "no", "yes", "no", NA, "yes", "no")

# 循环处理每个分类变量
for (var in c("smoker", "drinker")) {
  freq_obj <- freq(df[[var]], report.nas = FALSE)
  result_table <- getSummary(freq_obj)
  
  # 输出带标题的kable表格
  cat(paste0("\n### ", var, " 频率表(排除缺失值)\n"))
  print(kable(result_table, align = "c", caption = paste(var, "有效观测频率统计")))
}

内容的提问来源于stack exchange,提问作者Kristine

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 05:35:16