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

如何按分组变量展开二进制变量并将数据集转为宽格式?

我懂你现在的困扰——想把长格式数据转成宽格式,每个ID单独占一行,而且DOB和Age这些每个ID唯一的信息只保留一列,同时把Outcome拆成多列,之前用tidyr或者reshape的时候还碰到了重复相关的报错对吧?别着急,咱们用tidyr的pivot_wider()就能完美解决这个问题,关键是要告诉函数怎么处理同一个ID下的多个Outcome值。

先给你模拟一份和你场景匹配的原始数据,方便你对照:

library(tidyr)
library(dplyr)

# 模拟你的长格式数据集
df <- tibble(
  ID = c(1,1,2,2,3),
  DOB = c("1990-01-01", "1990-01-01", "1985-05-05", "1985-05-05", "2000-10-10"),
  Age = c(34,34,39,39,24),
  Outcome = c("A", "B", "A", "C", "B")
)

方案1:把多个Outcome转成带序号的列

如果你的每个ID对应多个不同的Outcome结果,想要把它们拆成Outcome_1、Outcome_2这样的列,可以先给每个ID下的Outcome加个序号,再转宽:

df_wide <- df %>%
  group_by(ID) %>%
  mutate(outcome_seq = row_number()) %>% # 给每个ID的Outcome按顺序编号
  ungroup() %>%
  pivot_wider(
    id_cols = c(ID, DOB, Age), # 指定作为唯一标识的列(这些列每个ID只有唯一值)
    names_from = outcome_seq,
    values_from = Outcome,
    names_prefix = "Outcome_" # 给生成的列名加前缀
  )

运行后你会得到每个ID一行,DOB和Age各一列,不同的Outcome分别放在带序号的列里。

方案2:把Outcome转成二进制指示列

如果你的Outcome是固定的几个类别(比如A、B、C),想要把每个类别变成单独的列,用1/0标记该ID是否有这个结果,可以这么写:

df_wide_binary <- df %>%
  pivot_wider(
    id_cols = c(ID, DOB, Age),
    names_from = Outcome,
    values_from = Outcome,
    values_fn = ~1, # 只要存在该Outcome就标记为1
    values_fill = 0 # 不存在则填充0
  )

这样生成的宽表会有A、B、C这类列,对应的值表示该ID是否有这个结果。

为什么之前会报错?

你之前碰到的重复相关错误,是因为默认情况下pivot_wider发现同一个ID(加上DOB、Age)对应多个Outcome值时,不知道该怎么聚合这些值。通过上面两种方式——要么给Outcome加序号让每个组合唯一,要么用values_fn指定聚合规则(比如标记存在与否),就能避免这个冲突啦。

内容的提问来源于stack exchange,提问作者user183974

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:19:08