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

R语言:保留各连续数值序列首项,其余重复值替换为NA(求dplyr方案)

问题需求

需要处理数据框中的x列,保留每一段连续非NA数值序列的首个实例,将序列内其余重复数值替换为NA。

示例输入

输入数据集代码:

x = c(1,1,1,NA,NA,NA,3,3,3,NA,NA,1,1,1,NA)
data = data.frame(x)

输入数据展示:

x
1   1
2   1
3   1
4  NA
5  NA
6  NA
7   3
8   3
9   3
10 NA
11 NA
12  1
13  1
14  1
15 NA

期望输出

x
1   1
2  NA
3  NA
4  NA
5  NA
6  NA
7   3
8  NA
9  NA
10 NA
11 NA
12  1
13 NA
14 NA
15 NA
dplyr实现方案

可以通过标记连续非NA序列并分组,再在每组内仅保留第一个值的方式实现:

library(dplyr)

result <- data %>%
  # 生成分组ID:每遇到新的非NA段(前一个值为NA或当前是第一行),分组ID累加
  mutate(group_id = cumsum(!is.na(x) & (is.na(lag(x)) | row_number() == 1))) %>%
  # 按分组ID分组
  group_by(group_id) %>%
  # 仅保留每组第一个值,其余替换为NA
  mutate(x = ifelse(row_number() == 1, x, NA)) %>%
  # 取消分组并移除临时分组列
  ungroup() %>%
  select(-group_id)

print(result)

代码说明

  • cumsum(!is.na(x) & (is.na(lag(x)) | row_number() == 1)):通过累加判断条件,为每一段连续的非NA值分配唯一的分组ID,确保同一段连续非NA值在同一组。
  • group_by(group_id):基于生成的分组ID对数据分组。
  • ifelse(row_number() == 1, x, NA):在每个分组内,仅保留第一行的原x值,其余行替换为NA。
  • ungroup()和select(-group_id):清理临时分组标识,得到干净的结果数据框。

简洁替代方案(结合data.table)

如果可以引入data.table包,rleid函数能更高效地生成连续序列的分组ID:

library(dplyr)
library(data.table)

result <- data %>%
  mutate(group_id = rleid(is.na(x))) %>%
  group_by(group_id) %>%
  mutate(x = ifelse(row_number() == 1 & !is.na(x), x, NA)) %>%
  ungroup() %>%
  select(-group_id)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 13:35:34