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

如何用dplyr按条件拆分行并复制其余列字符串值?

使用dplyr按条件拆分行的解决方案

可以通过dplyr结合tidyr的函数实现需求,全程无需循环,具体代码如下:

library(dplyr)
library(tidyr)

# 原始数据
df <- tibble(
  Group_ID = c(1,2,3,4,5,6),
  statusA = c("NEW", "NEW", "OLD","NEW", "OLD","OLD"),
  statusB = c("BONUS", NA, "BONUS", NA, NA,"ROLLBACK"),
  someVar = c("Thanks", "for", "your", "help","!","!")
)

# 处理逻辑
df_processed <- df %>%
  # 标记需要拆分的行(statusB非NA)
  mutate(split_flag = !is.na(statusB)) %>%
  # 为拆分行生成2行,非拆分行保留1行
  expand(nesting(Group_ID, someVar, statusA, statusB, split_flag),
         row_id = ifelse(split_flag, 1:2, 1)) %>%
  # 按行号设置statusA和statusB的值
  mutate(
    statusA = case_when(
      split_flag & row_id == 1 ~ statusA,
      split_flag & row_id == 2 ~ NA_character_,
      TRUE ~ statusA
    ),
    statusB = case_when(
      split_flag & row_id == 1 ~ NA_character_,
      split_flag & row_id == 2 ~ statusB,
      TRUE ~ statusB
    )
  ) %>%
  # 移除辅助列并调整顺序、排序
  select(-split_flag, -row_id) %>%
  select(Group_ID, statusA, statusB, someVar) %>%
  arrange(Group_ID)

结果验证

运行以下代码可以确认处理后的数据和预期一致:

# 预期数据
desired_df <- tibble(
  Group_ID = c(1,1,2,3,3,4,5,6,6),
  statusA = c("NEW",NA,"NEW","OLD",NA,"NEW","OLD","OLD",NA),
  statusB = c(NA,"BONUS",NA,NA,"BONUS",NA,NA,NA,"ROLLBACK"),
  someVar = c("Thanks","Thanks", "for", "your","your","help","!","!","!")
)

# 对比验证
all.equal(df_processed, desired_df)
# 输出:[1] TRUE

逻辑说明

  1. 标记拆分行:用split_flag标识statusB非NA的行,这些行需要拆分
  2. 生成多行结构:通过expand函数为拆分行生成两行记录,非拆分行保持一行
  3. 赋值调整:利用case_when对拆分后的两行分别设置statusA和statusB的值,实现一行保留原statusA、一行保留原statusB的效果
  4. 整理结果:移除辅助列,调整列顺序并按Group_ID排序,得到最终目标数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:07:24