如何让gtsummary基于ITime类型正确展示时间统计量?
问题描述
我有POSIXct格式的医院入院时间(例如"1899-12-31 13:11:00"),无需关注日期,因此用lubridate包提取时分秒并格式化为%H:%M:%S,再转换为ITime类型(该类型以当日秒数整数存储),方便计算入院时间的均值、中位数、最值等统计量。
单独计算统计量时结果正常,比如执行mean(sample_data$HOSP_ADMSN_TIME.x)会输出预期的"14:11:18"。但将该变量传入gtsummary生成汇总表时,它把变量视为连续变量,均值显示为57078(秒数)而非预期的时间格式。
核心需求:让gtsummary基于ITime类型处理时间戳,计算并展示正确格式的统计量。
示例数据集
# A tibble: 10 × 1 HOSP_ADMSN_TIME.x <dttm> 1 2021-04-19 10:00:00 2 2021-05-02 09:18:00 3 2021-09-09 15:06:00 4 2021-08-17 13:10:00 5 2022-01-18 11:44:00 6 2021-10-13 20:33:00 7 2021-05-06 19:09:00 8 2021-08-04 12:49:00 9 2021-11-15 11:00:00 10 2021-09-01 19:04:00
数据处理代码
sample_data$HOSP_ADMSN_TIME.x <- format(ymd_hms(sample_data$HOSP_ADMSN_TIME.x), "%H:%M:%S") sample_data$HOSP_ADMSN_TIME.x <- as.ITime(sample_data$HOSP_ADMSN_TIME.x)
验证统计量计算
mean(sample_data$HOSP_ADMSN_TIME.x) [1] "14:11:18"
当前gtsummary汇总表代码
sample_data %>% tbl_summary( label = list(HOSP_ADMSN_TIME.x ~ "Hospital Admission Time"), missing = "ifany", missing_text = "Missing", type = HOSP_ADMSN_TIME.x ~ "continuous2", statistic = HOSP_ADMSN_TIME.x ~ c("{mean}", "{median} ({p25}, {p75})", "{min}, {max}") ) %>% bold_labels() %>% modify_header(label ~ "**Variable**")
(当前生成的表格中均值显示为57,078而非预期时间格式)
解决方案
gtsummary默认会读取ITime类型变量的底层存储值(秒数整数)来生成统计量,因此需要通过自定义逻辑将计算结果转回时间格式,以下是三种可行方法:
方法1:自定义统计表达式
直接在statistic参数中使用自定义表达式,计算后将秒数结果转换为ITime格式再输出:
sample_data %>% tbl_summary( label = list(HOSP_ADMSN_TIME.x ~ "Hospital Admission Time"), missing = "ifany", missing_text = "Missing", type = HOSP_ADMSN_TIME.x ~ "continuous2", statistic = HOSP_ADMSN_TIME.x ~ list( ~ as.character(as.ITime(mean(.x))), ~ sprintf("%s (%s, %s)", as.character(as.ITime(median(.x))), as.character(as.ITime(quantile(.x, 0.25))), as.character(as.ITime(quantile(.x, 0.75)))), ~ sprintf("%s, %s", as.character(as.ITime(min(.x))), as.character(as.ITime(max(.x)))) ) ) %>% bold_labels() %>% modify_header(label ~ "**Variable**")
方法2:提前计算统计量再传入
手动计算所有需要的统计量,直接将格式化后的结果传入statistic参数,适合需要精细控制的场景:
# 预先计算并格式化统计量 time_stats <- list( mean = as.character(as.ITime(mean(sample_data$HOSP_ADMSN_TIME.x))), median_iqr = sprintf("%s (%s, %s)", as.character(as.ITime(median(sample_data$HOSP_ADMSN_TIME.x))), as.character(as.ITime(quantile(sample_data$HOSP_ADMSN_TIME.x, 0.25))), as.character(as.ITime(quantile(sample_data$HOSP_ADMSN_TIME.x, 0.75)))), min_max = sprintf("%s, %s", as.character(as.ITime(min(sample_data$HOSP_ADMSN_TIME.x))), as.character(as.ITime(max(sample_data$HOSP_ADMSN_TIME.x)))) ) # 生成汇总表 sample_data %>% tbl_summary( label = list(HOSP_ADMSN_TIME.x ~ "Hospital Admission Time"), missing = "ifany", missing_text = "Missing", type = HOSP_ADMSN_TIME.x ~ "continuous2", statistic = HOSP_ADMSN_TIME.x ~ c(time_stats$mean, time_stats$median_iqr, time_stats$min_max) ) %>% bold_labels() %>% modify_header(label ~ "**Variable**")
方法3:注册ITime类型的全局处理规则
如果需要频繁处理ITime变量,可以注册一个gtsummary的全局统计函数,让它自动识别并格式化ITime类型的统计结果:
# 注册自定义统计函数 register_statistic( fn = function(data, variable, ...) { x <- data[[variable]] tibble( label = c("Mean", "Median (IQR)", "Min, Max"), stat = c( as.character(as.ITime(mean(x))), sprintf("%s (%s, %s)", as.character(as.ITime(median(x))), as.character(as.ITime(quantile(x, 0.25))), as.character(as.ITime(quantile(x, 0.75)))), sprintf("%s, %s", as.character(as.ITime(min(x))), as.character(as.ITime(max(x)))) ) ) }, type = "continuous", class = "ITime" ) # 之后直接调用tbl_summary即可自动处理ITime变量 sample_data %>% tbl_summary( label = list(HOSP_ADMSN_TIME.x ~ "Hospital Admission Time"), missing = "ifany", missing_text = "Missing" ) %>% bold_labels() %>% modify_header(label ~ "**Variable**")
内容的提问来源于stack exchange,提问作者emvirgen
相关产品推荐
相关产品推荐

