如何在R中将两个melt/gather/pivot_longer命令合并为单个命令?
宽表转长表:同时处理time/count多组列的解决方案
错误原因说明
你遇到的问题是因为**reshape2::melt 不支持 data.table::patterns 参数**——patterns 是data.table包中melt函数的专属语法,混用两个包的函数会导致找不到对应参数或匹配失败的错误。
方案1:使用data.table的melt(高效原生支持多组列)
data.table的melt函数原生支持多组列的批量重塑,直接通过patterns匹配列名前缀即可:
library(data.table) # 将data.frame转为data.table setDT(df) # 一次完成多组列的宽转长 long_df <- melt(df, id.vars = "id", # 保留的标识符列 measure.vars = patterns(time = "^time", count = "^count"), # 匹配两组列的前缀 variable.name = c("group_num"), # 提取的分组编号(1-4) value.name = c("time_count_value", "count_value") # 对应值的列名 ) # 将分组编号转为要求的timepoint/count_no格式 long_df[, `:=`( timepoint = paste0("time", group_num), count_no = paste0("count", group_num) )][, group_num := NULL] # 删除临时分组列 # 调整列顺序以匹配目标格式 setcolorder(long_df, c("timepoint", "time_count_value", "count_no", "count_value", "id"))
方案2:使用tidyr的pivot_longer(tidyverse风格,语法直观)
利用tidyr的pivot_longer结合正则表达式提取列名中的前缀和编号,一次完成重塑:
library(tidyr) library(dplyr) long_df <- df %>% # 匹配所有time和count开头的列,提取前缀和数字编号 pivot_longer( cols = starts_with(c("time", "count")), names_to = c(".value", "group_num"), names_pattern = "(time|count)(\\d)" # 正则捕获:前缀(time/count)+ 数字 ) %>% # 生成要求的timepoint和count_no列 mutate( timepoint = paste0("time", group_num), count_no = paste0("count", group_num) ) %>% # 调整列顺序并删除临时分组列 select(timepoint, time_count_value = time, count_no, count_value = count, id) %>% arrange(id, group_num) %>% select(-group_num)
方案3:reshape2分两次合并(兼容旧版工具链)
如果必须使用reshape2,可以分别重塑time和count列,再通过分组编号合并:
library(reshape2) # 重塑time列 time_long <- melt(df, id.vars = "id", measure.vars = starts_with("time"), variable.name = "timepoint", value.name = "time_count_value") %>% mutate(group_num = gsub("time", "", timepoint)) # 重塑count列 count_long <- melt(df, id.vars = "id", measure.vars = starts_with("count"), variable.name = "count_no", value.name = "count_value") %>% mutate(group_num = gsub("count", "", count_no)) # 合并并整理格式 long_df <- merge(time_long, count_long, by = c("id", "group_num")) %>% select(timepoint, time_count_value, count_no, count_value, id) %>% arrange(id, group_num) %>% select(-group_num)
内容的提问来源于stack exchange,提问作者Feli
相关产品推荐
相关产品推荐

