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

R语言频率表取整求助:arsenal包tableby函数取整方案

问题:arsenal包tableby函数频数取整及替代方案

我在R/RMarkdown中使用arsenal包的tableby()生成频率表,该工具便于集成到docx/html文档中,但需要将频数取整至最接近的5或10。尝试通过tableby.control()设置digits=-1失败,系统提示digits需≥0。

模拟数据集与常规表生成流程

set.seed(1234)

library(dplyr)
library(arsenal)

x1 <- c(rep("Man",40),rep("Woman",60)) %>% as.factor()
x2 <- sample(c("Sick","Healthy"),100,replace=TRUE) %>% as.factor()

df <- data.frame(x1,x2)

Control_notrounded <- tableby.control(digits=0,digits.pct=2,cat.stats=c("countpct","Nmiss2"))

table <- tableby(x1~x2,control=Control_notrounded,data=df)
print(summary(table))

失败的取整尝试

Control_rounded <- tableby.control(digits=-1,digits.pct=2,cat.stats=c("countpct","Nmiss2"))
table2 <- tableby(x1~x2,control=Control_rounded,data=df)
print(summary(table2))

可行解决方案

方案1:手动处理arsenal生成的表格结果

arsenal的summary()输出可转换为数据框,之后手动对频数进行取整处理:

# 生成原始表
set.seed(1234)
library(dplyr)
library(arsenal)

x1 <- c(rep("Man",40),rep("Woman",60)) %>% as.factor()
x2 <- sample(c("Sick","Healthy"),100,replace=TRUE) %>% as.factor()
df <- data.frame(x1,x2)

Control_notrounded <- tableby.control(digits=0,digits.pct=2,cat.stats=c("countpct","Nmiss2"))
table <- tableby(x1~x2,control=Control_notrounded,data=df)
tab_summary <- summary(table, text=TRUE)

# 转换为数据框
tab_df <- as.data.frame(tab_summary)

# 定义取整函数(可切换取整到5或10)
round_to_nearest <- function(x, nearest=5) {
  round(x/nearest)*nearest
}

# 拆分、取整、重组频数与百分比
tab_df <- tab_df %>%
  mutate(
    count = as.numeric(sub("^(\\d+) \\((.*)\\)$", "\\1", `x2`)),
    pct = sub("^(\\d+) \\((.*)\\)$", "\\2", `x2`),
    count_rounded = round_to_nearest(count),
    x2 = paste0(count_rounded, " (", pct, ")")
  ) %>%
  select(-count, -pct, -count_rounded)

# 输出处理后的表格
print(tab_df, row.names=FALSE)

方案2:使用替代包生成带取整频数的表格

用gtsummary包(支持docx/html导出)

gtsummary支持自定义统计量格式,可直接嵌入取整逻辑:

library(gtsummary)

# 定义取整函数
round_to_nearest <- function(x, nearest=5) {
  round(x/nearest)*nearest
}

# 生成带取整频数的表格
df %>%
  tbl_summary(
    by = x1,
    statistic = list(all_categorical() ~ "{round_to_nearest(n)} ({p}%)"),
    digits = list(all_categorical() ~ c(0, 2))
  ) %>%
  as_flex_table() # 可导出为docx/html格式
用flextable+dplyr自定义生成表格

完全自定义表格内容,灵活性更高:

library(flextable)

# 计算频数、百分比并取整
freq_table <- df %>%
  group_by(x1, x2) %>%
  summarise(n = n(), .groups = "drop") %>%
  group_by(x1) %>%
  mutate(pct = round(n/sum(n)*100, 2)) %>%
  ungroup() %>%
  mutate(n_rounded = round_to_nearest(n)) %>%
  mutate(label = paste0(n_rounded, " (", pct, "%)")) %>%
  pivot_wider(names_from = x1, values_from = label)

# 转换为可导出的表格
freq_table %>%
  flextable() %>%
  autofit()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:23:19