R语言如何将相同ID的多行数据合并为一行多列格式
R语言长表转宽表实现方案
首先修正示例数据的列名一致性问题:你提供的数据定义和打印输出的列名存在小偏差,我们先统一列名,将学生编号列命名为id,第三列原value改为对应含义的time。
方法1:tidyverse 实现(更易读)
这是目前最常用的tidy数据处理方案,代码如下:
# 加载依赖包 library(tidyverse) # 构造统一列名的示例数据 df <- data.frame( id = c(1, 1, 2, 3, 3, 3), points = c(3, 4, 5, 2, 6, 8), time = c(5, 5, 6, 8, 6, 2) ) # 转换代码 df %>% # 按学生分组,给每个学生的测验按顺序生成a/b/c标签 group_by(id) %>% mutate(quiz_tag = letters[row_number()]) %>% ungroup() %>% # 转换为宽表,按要求生成列名 pivot_wider( id_cols = id, names_from = quiz_tag, values_from = c(points, time), names_glue = "{.value}-{quiz_tag}" )
方法2:base R 实现(无需安装额外包)
如果不想依赖第三方包,可以用内置的reshape函数实现:
# 构造统一列名的示例数据 df <- data.frame( id = c(1, 1, 2, 3, 3, 3), points = c(3, 4, 5, 2, 6, 8), time = c(5, 5, 6, 8, 6, 2) ) # 转换代码 # 为每个学生的测验生成a/b/c标签 df$quiz_tag <- ave(df$id, df$id, FUN = function(x) letters[seq_along(x)]) # 转宽表 res_df <- reshape( df, idvar = "id", timevar = "quiz_tag", direction = "wide", sep = "-" ) # 调整列顺序匹配需求 res_df <- res_df[, c("id", "points-a", "time-a", "points-b", "time-b", "points-c", "time-c")]
两种方法运行后均可得到你需要的输出结果,没有对应测验的字段会自动填充为NA。
内容的提问来源于stack exchange,提问作者bettina m.
相关产品推荐
相关产品推荐

