R语言长转宽格式:基于多列唯一组合处理重复数据
我太懂这种困扰了——手里的长格式数据集要转成宽格式,每个id占一行,但time、drug、unit、admin这四列的组合五花八门,手动列出来根本不现实对吧?别慌,用R里的data.table或者tidyverse工具就能轻松实现动态生成唯一列名的宽格式转换,我给你详细说说两种常用方法:
方法1:用data.table的dcast函数
既然你已经试过melt.data.table,那肯定熟悉data.table的语法,它的dcast函数就是专门用来长转宽的,完美适配你这种多列组合生成列名的需求。
假设你的长格式数据集叫dt,需要转换的数值列是value(记得换成你实际的列名),代码如下:
library(data.table) # 先把数据转为data.table格式(如果还不是的话) setDT(dt) # 执行宽格式转换,自动用time+drug+unit+admin的唯一组合生成列名 wide_dt <- dcast(dt, id ~ time + drug + unit + admin, value.var = "value")
这里的核心是公式id ~ time + drug + unit + admin:左边指定行分组的依据(id,保证每个id一行),右边的四个列会自动拼接成唯一的列名(默认用下划线分隔,比如morning_Aspirin_mg_oral),每个id对应的行里会填充对应组合的数值,没有匹配的组合则显示NA。
方法2:用tidyr的pivot_wider函数
如果你更习惯tidyverse的语法,tidyr的pivot_wider同样能搞定这个需求,而且语法更直观:
library(tidyr) library(dplyr) wide_df <- dt %>% pivot_wider( id_cols = id, # 指定行的分组依据是id names_from = c(time, drug, unit, admin), # 用这四列的组合生成新列名 values_from = value, # 指定要转换的数值列(替换成你的实际列名) names_sep = "_" # 自定义列名的分隔符,默认也是下划线,可修改 )
这个方法生成的列名逻辑和dcast一致,你还可以通过names_glue参数自定义列名的格式,比如names_glue = "{drug}_{time}_{unit}_{admin}"来调整列名的顺序。
小提醒
- 确认你的
id+time+drug+unit+admin组合是唯一的(你已经说明每个id里这四个组合唯一,所以转换后不会出现重复行或者警告) - 如果有多个数值列要转换,只需要在
value.var(dcast)或values_from(pivot_wider)里指定多个列名即可,比如value.var = c("dose", "effect")
内容的提问来源于stack exchange,提问作者User LG
相关产品推荐
相关产品推荐

