You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:18:08