如何在R中将多列宽表转换为包含所有列组合的长表?
解决方案:宽格式转含所有两两变量组合的长格式
可以用tidyverse工具包实现需求,核心思路是先生成a1至a4的所有两两组合,再针对每个组合从原数据中提取对应列并整理格式,最后合并所有结果:
library(tidyverse) # 定义原数据 dat0 <- structure(list(id = c(1, 2, 3, 4, 5), gp = c("A", "B", "C", "D", "E"), a1 = c(2, 4, 7, 8, 9), a2 = c(10, 20, 30, 40, 50), a3 = c(150, 200, 350, 400, 700), a4 = c(1000, 3000, 4000, 7000, 8000)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L)) # 生成a1-a4的所有两两组合 var_pairs <- combn(starts_with("a", vars = colnames(dat0)), 2, simplify = FALSE) # 遍历每个组合,提取对应列并整理格式,最后合并 dat1 <- map_dfr(var_pairs, function(pair) { dat0 %>% mutate( ax_vs_ay = str_c(pair, collapse = "_vs_"), ax = !!sym(pair[1]), ay = !!sym(pair[2]) ) %>% select(id, gp, ax_vs_ay, ax, ay) }) # 查看结果 print(dat1, n = 30)
代码说明
combn(starts_with("a", vars = colnames(dat0)), 2):自动识别原数据中以a开头的列,生成所有两两组合(共6组)。map_dfr():遍历每个组合,对原数据进行转换:str_c(pair, collapse = "_vs_"):生成ax_vs_ay列的分类标签。!!sym(pair[1]):将列名字符串转为变量,提取对应列的值作为ax,同理处理ay。select():保留需要的列并调整为期望的顺序。
- 最终合并后的结果完全匹配需求:每个
id和gp按组合数重复,包含所有两两变量组合,分类标签准确。
内容的提问来源于stack exchange,提问作者denis
相关产品推荐
相关产品推荐

