如何将每个id对应的两行数据合并为一行并新增两列?
问题描述
我当前的数据中每个id对应恰好两行,希望将其合并为指定格式的单行。尝试过使用pivot_wider(),但生成的列数过多,仅需新增name1/value1、name2/value2两组列,请问该如何实现?
当前数据结构
tibble::tribble( ~id, ~n, ~prop, ~name, ~value, "1", 135L, 0.918367346938776, "q1", "Y", "1", 135L, 0.918367346938776, "q2", "Y", "3", 225L, 0.945378151260504, "q1", "Y", "3", 225L, 0.945378151260504, "q3", "Y", "5", 446L, 0.944915254237288, "q1", "Y", "5", 446L, 0.944915254237288, "q4", "Y" ) #> # A tibble: 6 x 5 #> id n prop name value #> <chr> <int> <dbl> <chr> <chr> #> 1 1 135 0.918 q1 Y #> 2 1 135 0.918 q2 Y #> 3 3 225 0.945 q1 Y #> 4 3 225 0.945 q3 Y #> 5 5 446 0.945 q1 Y #> 6 5 446 0.945 q4 Y
期望数据结构
tibble::tribble( ~id, ~n, ~prop, ~name1, ~value1, ~name2, ~value2, "1", 135L, 0.918367346938776, "q1", "Y", "q2", "Y", "3", 225L, 0.945378151260504, "q1", "Y", "q3", "Y", "5", 446L, 0.944915254237288, "q1", "Y", "q4", "Y" ) #> # A tibble: 3 x 7 #> id n prop name1 value1 name2 value2 #> <chr> <int> <dbl> <chr> <chr> <chr> <chr> #> 1 1 135 0.918 q1 Y q2 Y #> 2 3 225 0.945 q1 Y q3 Y #> 3 5 446 0.945 q1 Y q4 Y
解决方案
核心思路是先给每个id内的两行添加序号标识,再通过pivot_wider()按序号展开列,避免生成过多无关列:
library(tidyverse) # 加载原始数据 df <- tibble::tribble( ~id, ~n, ~prop, ~name, ~value, "1", 135L, 0.918367346938776, "q1", "Y", "1", 135L, 0.918367346938776, "q2", "Y", "3", 225L, 0.945378151260504, "q1", "Y", "3", 225L, 0.945378151260504, "q3", "Y", "5", 446L, 0.944915254237288, "q1", "Y", "5", 446L, 0.944915254237288, "q4", "Y" ) # 数据处理 df_processed <- df %>% # 按id分组,给每组内的行添加序号(1、2) group_by(id) %>% mutate(row_num = row_number()) %>% ungroup() %>% # 按序号展开name和value列,指定列名格式 pivot_wider( id_cols = c(id, n, prop), names_from = row_num, values_from = c(name, value), names_glue = "{.name}{row_num}" ) print(df_processed)
运行后即可得到期望的单行结构,row_num的作用是让pivot_wider()仅按行的顺序生成两组列,而非按name的不同取值生成大量列。
内容的提问来源于stack exchange,提问作者joshbrows
相关产品推荐
相关产品推荐

