如何在R中合并多变量FND症状并统计单症状分层频率
问题描述
我正在开展一项研究,旨在对比接受特定脑外科手术患者的术后并发症。其中一项分析需使用CreateTableOne函数对比患者术后的FND(局灶性神经功能缺损)症状。目前症状被收集为四个分类变量FNDtype、FNDtype2、FNDtype3、FNDtype4,每个患者最多有4种症状,部分患者更少。我尝试用paste函数将这些变量合并为一个,但使用CreateTableOne生成描述性分析时,结果显示的是症状组合的统计数据,而非单个症状在各分层组中的频率。
相关R代码
# Postcraniectomia Infection data$postcraniotomy_infection <- factor(data$`Postcraniotomy infection (y=1, n=0)`, levels = c(0,1), labels = c("no", "yes")) # FND Type data$FNDtype <- factor(data$`Type of FND (1)`, levels = c(0,1,2,3,4,5,6,7,8,9), labels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect","dysarthria","other")) # FND Type 2 data$FNDtype2 <- factor(data$`Type of FND (2)`, levels = c(0,1,2,3,4,5,6,7,8,9), labels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect","dysarthria","other")) # FND Type 3 data$FNDtype3 <- factor(data$`Type of FND (3)`, levels = c(0,1,2,3,4,5,6,7,8,9), labels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect","dysarthria","other")) # FND Type 4 data$FNDtype4 <- factor(data$`Type of FND (4)`, levels = c(0,1,2,3,4,5,6,7,8,9), labels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect","dysarthria","other")) # Trying to merge FND Types into one variable data$fndtype <- paste(data$FNDtype, data$FNDtype2, data$FNDtype3, data$FNDtype4, sep = ",") vars <- c("fndtype") table <- CreateTableOne(vars = vars, data = data, strata = c("primary_infection"), testNonNormal = kruskal.test, addOverall = TRUE) kableone(table, nonnormal = vars)
数据集
list(postcraniotomy_infection = structure(c(2L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 1L), levels = c("no", "yes"), class = "factor"), FNDtype = structure(c(1L, 2L, 2L, 1L, 2L, 1L, 8L, 2L, 4L, 4L, 1L, 3L, 4L, 2L, 2L, 4L, 2L, 3L, 1L, 1L, 1L, 3L, 1L, 9L, 7L, 1L, 2L, 2L, 1L, 1L, 5L, 1L, 3L, 1L, 2L, 3L, 3L, 2L, 4L, 2L, 1L, 10L, 2L, 1L, 3L, 6L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 6L, 1L, 5L, 10L, 1L, 1L, 2L, 10L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 5L, 5L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 2L, 5L, 3L, 1L, 3L, 1L), levels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect", "dysarthria", "other" ), class = "factor"), FNDtype2 = structure(c(1L, 1L, 1L, 1L, 3L, 1L, 1L, 5L, 1L, 8L, 1L, 7L, 1L, 4L, 1L, 7L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 8L, 7L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 7L, 1L, 6L, 6L, 3L, 1L, 1L, 6L, 1L, 9L, 10L, 1L, 1L, 1L, 1L, 1L, 3L, 1L, 1L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 4L, 1L, 4L, 9L, 6L, 1L, 4L, 1L, 6L, 1L), levels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect", "dysarthria", "other"), class = "factor"), FNDtype3 = structure(c(1L, 1L, 1L, 1L, 6L, 1L, 1L, 8L, 1L, 1L, 1L, 8L, 1L, 7L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 9L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 6L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 1L, 1L, 10L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 8L, 1L, 6L, 1L, 9L, 1L, 1L, 1L, 1L, 1L), levels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect", "dysarthria", "other" ), class = "factor"), FNDtype4 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 9L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 8L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 10L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L ), levels = c("none", "hemiparesis", "hypoesthesia", "aphasia", "visual field defects", "coordiantion disturbance", "cranial nerve dysfunction", "neglect", "dysarthria", "other"), class = "factor"))
解决方案
要统计单个症状在各分层组中的频率,不能直接用paste合并变量(这会生成症状组合),正确的做法是将多个FND变量转换为长格式数据,标记每个症状的存在情况后再转为宽格式的二元变量,最后用CreateTableOne分析这些二元变量。
步骤1:加载必要的包
library(tableone) library(dplyr) library(tidyr)
步骤2:转换数据格式并生成症状二元变量
# 提取FND相关列,转换为长格式 fnd_long <- data %>% select(postcraniotomy_infection, starts_with("FNDtype")) %>% pivot_longer(cols = starts_with("FNDtype"), names_to = "fnd_col", values_to = "symptom") %>% # 排除无病症的记录 filter(symptom != "none") %>% # 标记症状存在 mutate(present = 1) %>% # 去重,避免同一患者同一症状重复计数 distinct(postcraniotomy_infection, symptom, .keep_all = TRUE) # 转换为宽格式,每个症状对应一列,未出现的症状填0 fnd_wide <- fnd_long %>% pivot_wider(names_from = symptom, values_from = present, values_fill = 0) %>% # 合并回原数据的分层变量(若原分层变量是primary_infection,替换此处的postcraniotomy_infection) right_join(data %>% select(postcraniotomy_infection), by = "postcraniotomy_infection") %>% # 将缺失值替换为0,表示未出现该症状 mutate(across(where(is.numeric), ~replace_na(.x, 0)))
步骤3:用CreateTableOne分析单个症状
# 获取所有症状变量名 symptom_vars <- setdiff(colnames(fnd_wide), "postcraniotomy_infection") # 创建描述性表格,按分层变量分组(若原分层变量是primary_infection,替换此处的postcraniotomy_infection) table <- CreateTableOne(vars = symptom_vars, data = fnd_wide, strata = "postcraniotomy_infection", addOverall = TRUE) # 输出结果 kableone(table)
关键说明
- 该方法会生成每个症状在各分层组中的频率(百分比),而非症状组合的统计结果。
- 若原代码中的分层变量是
primary_infection,请将上述代码中的postcraniotomy_infection统一替换为该变量名。 - 转换过程自动过滤了"none"的记录,仅统计实际出现的症状。
内容的提问来源于stack exchange,提问作者Massimo Barbagallo
相关产品推荐
相关产品推荐

