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

基于dplyr实现按列值条件合并行:合并同一ID下Event1与Event2行并保留Event3行

解决方案:用dplyr优雅合并ID的前两行并保留第三行

我来帮你搞定这个需求,用dplyr完全可以优雅解决,不用头疼后续合并的麻烦!你的核心需求是每个ID下合并event1和event2的非NA值为一行(保留event1的标识),同时完整保留每个ID的event3行,之前用summarise_all的方法确实会带来后续join的困扰,我们换个思路直接在分组内处理:

具体思路

对每个ID分组后,拆分出两部分数据分别处理,再合并回一起:

  • 合并event1和event2行:筛选出event为1和2的行,提取每列的非NA值(你的数据里每个score类列在这两行里只有一个有效值),然后把event固定为1;
  • 保留原event3行:直接筛选出event为3的行,完全保留原始数据;
  • 最后把这两部分在每个组内绑定,得到最终结果。

完整代码

library(dplyr)
library(tibble)

# 原始数据构造
id <- c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5)
event <- c(1,2,3,1,2,3,1,2,3,1,2,3,1,2,3)
score <- c(3,NA,1,3,NA,2,6,NA,1,8,NA,2,4,NA,1)
score2 <- c(NA,4,1,NA,5,2,NA,0,3,NA,5,6,NA,8,7)
df <- tibble(id, event, score, score2)

# 核心处理代码
df_final <- df %>%
  group_by(id) %>%
  group_modify(function(.x, .y) {
    # 合并event1和event2的行
    merged_row <- .x %>%
      filter(event %in% 1:2) %>%
      summarise(
        event = 1,  # 合并后保留event1的标识
        across(starts_with("score"), ~ .x[!is.na(.x)])  # 自动处理所有score开头的列,不管数量多少
      )
    # 保留event3的原始行
    event3_row <- .x %>% filter(event == 3)
    # 绑定两部分数据
    bind_rows(merged_row, event3_row)
  }) %>%
  ungroup()

# 查看最终结果
df_final

代码细节说明

  • group_modify:dplyr里专门用来对每个分组做自定义处理的函数,完美适配这种组内拆分再合并的场景;
  • across(starts_with("score"), ~ .x[!is.na(.x)]):用starts_with可以自动匹配所有score类列(哪怕你有300个),不需要逐个列写逻辑,自动提取每列的非NA值;
  • 全程在分组内完成所有操作,完全不需要后续的join步骤,从根源上避免了大量.x/.y列的麻烦。

最终输出结果

运行后得到的结果和你期望的完全一致:

# A tibble: 10 x 4
     id event score score2
   <dbl> <dbl> <dbl>  <dbl>
 1     1     1     3      4
 2     1     3     1      1
 3     2     1     3      5
 4     2     3     2      2
 5     3     1     6      0
 6     3     3     1      3
 7     4     1     8      5
 8     4     3     2      6
 9     5     1     4      8
10     5     3     1      7

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:39:10