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

R语言数据整理:长格式转宽格式(动态列实现难题)

解决方案

你可以通过拆分处理两类记录(REC="YES"和REC="NO")再合并的方式实现需求,具体代码如下:

library(dplyr)
library(tidyr)

# 处理原始数据并转换为目标宽格式
result <- A %>%
  group_by(ID) %>%
  # 为YES/NO类型的记录分别生成序号,用于动态列命名
  mutate(
    rec_seq = if_else(REC == "YES", row_number()[REC == "YES"], NA_integer_),
    reop_seq = if_else(REC == "NO", row_number()[REC == "NO"], NA_integer_)
  ) %>%
  ungroup() %>%
  # 处理REC="YES"的记录,生成RECn_DATE列
  pivot_wider(
    id_cols = c(ID, NR, INDX.DATE),
    names_from = rec_seq,
    values_from = REOP_DATE,
    names_prefix = "REC"
  ) %>%
  # 合并REC="NO"的处理结果
  left_join(
    A %>%
      filter(REC == "NO") %>%
      group_by(ID) %>%
      mutate(reop_seq = row_number()) %>%
      ungroup() %>%
      # 找出TYPE列中值为1的对应编号(如TYPE3对应3)
      rowwise() %>%
      mutate(REOP_TYPE = which(c_across(starts_with("TYPE")) == 1)) %>%
      ungroup() %>%
      # 生成REOPn_DATE和REOPn_TYPE动态列
      pivot_wider(
        id_cols = ID,
        names_from = reop_seq,
        values_from = c(REOP_DATE, REOP_TYPE),
        names_sep = "_"
      ),
    by = "ID"
  ) %>%
  # 填充同一ID的NR和INDX.DATE(原始数据仅第一行有值)
  group_by(ID) %>%
  mutate(
    NR = first(na.omit(NR)),
    INDX.DATE = first(na.omit(INDX.DATE))
  ) %>%
  ungroup() %>%
  # 保留每个ID的唯一行
  distinct(ID, .keep_all = TRUE)

# 输出结果
print(result)

代码说明

  1. 标记序号:按ID分组后,为REC="YES"的记录生成rec_seq序号,为REC="NO"的记录生成reop_seq序号,确保转宽时能生成带编号的动态列。
  2. 处理YES记录:通过pivot_wider将REOP_DATE转换为REC1_DATE、REC2_DATE等列。
  3. 处理NO记录:先筛选出REC="NO"的行,找出TYPE列中值为1的列对应的编号(如TYPE3值为1时,REOP_TYPE为3),再通过pivot_wider生成REOPn_DATE和REOPn_TYPE列。
  4. 合并与填充:将两部分结果按ID合并,填充同一ID的NR和INDX.DATE值,最后去重得到每个ID的单行结果。

运行上述代码后,输出结果将完全匹配你需要的宽格式结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 04:15:42