如何在R语言中按两列分组并将第三列转为宽格式?
解决R数据框按前两列分组转宽格式的问题
这里给你两种实用的方法,都能快速得到你想要的结果:
方法一:使用tidyverse(tidyr::pivot_wider)
核心思路是先给每个分组内的行添加序号,再用pivot_wider根据序号将第三列拆成多列:
library(tidyverse) # 你的原始数据框 df <- data.frame("first" = c("A","A","B","B","B"), "second" = c("C","C","D","D","Z"), "third" = c("E","F","G","H","I")) # 生成宽格式数据 df_wide <- df %>% # 按first和second分组,给每组内的行编序号 group_by(first, second) %>% mutate(col_index = row_number()) %>% ungroup() %>% # 转宽:id_cols是保留的分组列,values_from是要拆分的列,names_from用序号当新列名 pivot_wider(id_cols = c(first, second), values_from = third, names_from = col_index, names_prefix = "col_") # 查看结果 df_wide
运行后输出:
# A tibble: 3 × 4 first second col_1 col_2 <chr> <chr> <chr> <chr> 1 A C E F 2 B D G H 3 B Z I NA
如果想要和你示例里的third、fourth列名,直接重命名即可:
colnames(df_wide)[3:4] <- c("third", "fourth")
方法二:使用data.table(适合大数据量)
如果你的数据量很大,data.table的dcast效率更高:
library(data.table) setDT(df) # 用rowid生成分组内的序号,直接转宽 df_wide <- dcast(df, first + second ~ rowid(first, second), value.var = "third") # 重命名列名匹配你的需求 setnames(df_wide, c("first", "second", "third", "fourth")) df_wide
输出结果和你期望的完全一致:
first second third fourth 1: A C E F 2: B D G H 3: B Z I <NA>
为什么之前嵌套反嵌套没成功?
你之前尝试的嵌套反嵌套思路没问题,但关键是没给每个分组内的元素分配唯一的标识,转宽操作需要明确每个值对应哪一列,所以必须先给每组内的行添加序号(比如上面的row_number()或rowid),这样pivot_wider或dcast才能正确拆分列。
内容的提问来源于stack exchange,提问作者Lucius
相关产品推荐
相关产品推荐

