请求优化tern包format_xx()保留rounding后末尾0并适配analyze_vars
解决tern包format_xx()丢弃末尾0的问题
问题原因
直接用字符串格式(如'xx.xx')调用format_value()时,会严格按模板保留指定小数位;但format_xx()返回的格式化函数,内部处理时会自动去除数值末尾的无效0,导致输出和预期不符。
解决方案
1. 针对mean_sd的自定义格式化函数
如果只需要处理mean_sd这类统计量,可以写一个专用函数,分别格式化均值和标准差后拼接,确保保留指定小数位:
library(dplyr) library(rtables) library(tern) # 自定义保留末尾0的mean_sd格式化函数 format_mean_sd_fixed <- function(x) { # 均值保留1位小数,标准差保留2位小数 mean_str <- format_value(x[1], format = "xx.x") sd_str <- format_value(x[2], format = "xx.xx") paste0(mean_str, " (", sd_str, ")") } # 构建表格 lyt <- basic_table() %>% split_cols_by(var = 'ARM') %>% analyze_vars( vars = 'AGE', .stats = c("mean_sd"), .formats = c("mean_sd" = format_mean_sd_fixed), .labels = c("mean_sd" = "Mean (SD)") ) build_table(lyt, pharmaverseadam::adsl)
运行后,SD部分会严格保留两位小数,比如原本的9.7会变成9.70。
2. 通用复合格式函数
如果需要支持更多类似xx.x (xx.xx)的复合格式,可以写一个通用函数,自动拆分模板并分别格式化:
# 通用保留末尾0的复合格式函数 format_xx_fixed <- function(format_str) { # 匹配带括号的复合格式(如xx.x (xx.xx)) template_match <- stringr::str_match(format_str, "(.*)\\((.*)\\)") if (!is.na(template_match[1, 1])) { # 拆分并清理两个格式模板 fmt1 <- trimws(template_match[1, 2]) fmt2 <- trimws(template_match[1, 3]) function(x) { val1 <- format_value(x[1], format = fmt1) val2 <- format_value(x[2], format = fmt2) paste0(val1, " (", val2, ")") } } else { # 处理单一格式(如xx.xx) function(x) format_value(x, format = format_str) } } # 使用通用函数构建表格 lyt <- basic_table() %>% split_cols_by(var = 'ARM') %>% analyze_vars( vars = 'AGE', .stats = c("mean_sd"), .formats = c("mean_sd" = format_xx_fixed("xx.x (xx.xx)")), .labels = c("mean_sd" = "Mean (SD)") ) build_table(lyt, pharmaverseadam::adsl)
功能增强建议
如果希望tern原生支持该功能,可以前往tern包的GitHub仓库提交Feature Request,说明需求:为format_xx()增加参数,控制是否保留格式化后的末尾0。
内容的提问来源于stack exchange,提问作者Peng Zhang
相关产品推荐
相关产品推荐

