如何将纵向数据从宽格式转长格式并批量处理多变量及缺失值?
问题
原始数据集结构如下:
Id smoke_2m Smoke_3m smoke_4m alcohol_3m age sex 1 2 3 5 7 30 M 2 3 3 5 6 26 M 3 7 5 7 2 25 F
期望转换为长格式数据:
Id Time smoking alcohol age sex 1 2m 2 - 30 M 1 3m 3 7 30 M 1 4m 5 - 30 M 2 2m 3 - 26 M 2 3m 3 6 26 M 2 4m 5 - 26 M 3 2m 7 - 25 F 3 3m 5 2 25 F 3 4m 7 - 25 F
其中alcohol仅在3m时间点有数据,其余时间点需要填充为'-'。
我尝试了以下代码,但只能处理smoking单个变量:
data <- data %>% pivot_longer( cols = c(smoke_2m, smoke_3m, smoke_4m), names_to = "time_point", values_to = "smoking_status" )
请问如何实现所有变量的批量转换?
解决方案
可以通过拆分列名提取变量名和时间点,一次性完成多变量的长格式转换,再处理缺失值。具体代码如下:
library(tidyverse) # 先统一列名大小写(原数据中Smoke_3m首字母大写,避免匹配错误) data <- data %>% rename_with(tolower) # 批量转换为长格式,拆分变量名与时间点 data_long <- data %>% pivot_longer( cols = starts_with(c("smoke", "alcohol")), # 选中所有带时间后缀的列 names_to = c(".value", "Time"), # .value保留变量名,Time提取时间部分 names_pattern = "(.*)_(.*)" # 用下划线拆分列名:变量名_时间点 ) # 填充alcohol的缺失值为'-',调整列名和顺序 final_data <- data_long %>% mutate(alcohol = ifelse(is.na(alcohol), "-", as.character(alcohol))) %>% select(Id, Time, smoking = smoke, alcohol, age, sex)
代码说明:
- 统一列名大小写:原数据里
Smoke_3m首字母大写,转成小写后能保证正则拆分时不会漏处理这一列。 - 批量转换核心:
pivot_longer的names_pattern参数用正则把列名拆成两部分,.value是特殊关键字,会自动把同属一个变量的行合并成对应列,这样就能同时处理smoke和alcohol两类时间序列变量。 - 缺失值填充:非3m时间点的
alcohol会是NA,用ifelse把这些NA替换成'-',转成字符类型是为了和有值的行格式统一。 - 调整列结构:把
smoke重命名为smoking,再调整列的顺序,完全匹配你期望的结果。
运行这段代码后就能得到目标长格式数据,所有时间点的smoking和对应alcohol值都会正确展示,非3m时间点的alcohol自动填充为'-'。
内容的提问来源于stack exchange,提问作者Komal Mehta
相关产品推荐
相关产品推荐

