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

如何在R的tidyverse中按列唯一值生成新数据行(支持分组)

问题描述

原始数据集结构如下:

data <- data.frame(
  uniqueid = c(1, 1, 2, 2, 3, 3),
  year = c(2010, 2011, 2010, 2011, 2010, 2011),
  agency = c("SZ", "SZ", "SZ", NA, "SZ", "HE"),
  switch = c(0, 0, 0, NA, 0, 1)
)

需求:按uniqueid和year分组,为agency列的每个唯一值生成新行,switch变量遵循以下逻辑:

  • 与原始数据中该uniqueid-year-agency匹配的行,保留原switch值;
  • 若原始数据中该uniqueid-year的agency非NA,其他未匹配的agency对应的switch填0;
  • 若原始数据中该uniqueid-year的agency为NA,所有agency对应的switch保留NA。
正确解决方案

使用tidyverse工具链实现,步骤如下:

  1. 加载tidyverse包并定义原始数据:
library(tidyverse)

data <- data.frame(
  uniqueid = c(1, 1, 2, 2, 3, 3),
  year = c(2010, 2011, 2010, 2011, 2010, 2011),
  agency = c("SZ", "SZ", "SZ", NA, "SZ", "HE"),
  switch = c(0, 0, 0, NA, 0, 1)
)
  1. 提取所有agency的唯一值(包含NA):
all_agencies <- data %>% pull(agency) %>% unique()
  1. 生成目标结构数据:
result <- data %>%
  # 为每个uniqueid-year保存原始agency和switch值
  group_by(uniqueid, year) %>%
  mutate(original_agency = agency, original_switch = switch) %>%
  ungroup() %>%
  select(uniqueid, year, original_agency, original_switch) %>%
  distinct() %>%
  # 为每个uniqueid-year组合匹配所有agency值
  crossing(agency = all_agencies) %>%
  # 按逻辑设置switch值
  mutate(
    switch = case_when(
      agency == original_agency ~ original_switch,
      !is.na(original_agency) ~ 0,
      TRUE ~ NA_real_
    )
  ) %>%
  # 移除辅助列并排序
  select(-original_agency, -original_switch) %>%
  arrange(uniqueid, year, agency)

运行后得到的result即为需求的目标结构。

原代码问题说明

你之前的代码存在两处核心问题:

  • 错误引用了不存在的lead变量,应该使用switch;
  • pivot_wider+gather的方式无法处理原始agency为NA时的特殊逻辑,也不能正确填充switch的缺失值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 07:53:13