R语言按分组将val列扩展为连续递增序列的实现方法
问题说明
现有多组长度不等的观测构成的数据框,分组字段为var:
- 每组的
val列仅存在1个非NA值,其余均为NA,该非NA值可出现在组内任意行 - 需要按组将
val列填充为连续递增整数序列,要求原非NA值的位置、取值完全不变,其余位置按连续整数规则补全
示例输入
dat <- data.frame(var = c(rep("A", 3), rep("B", 4), rep("C",5)), val = c(4, NA, NA, NA, NA, 9, NA, NA, NA, NA, NA, 20)) dat # var val # 1 A 4 # 2 A NA # 3 A NA # 4 B NA # 5 B NA # 6 B 9 # 7 B NA # 8 C NA # 9 C NA # 10 C NA # 11 C NA # 12 C 20
期望输出
# var val # 1 A 4 # 2 A 5 # 3 A 6 # 4 B 7 # 5 B 8 # 6 B 9 # 7 B 10 # 8 C 16 # 9 C 17 # 10 C 18 # 11 C 19 # 12 C 20
实现方案
核心逻辑:以每组内唯一的非NA值为锚点,组内每向上一行数值减1,每向下一行数值加1,自然形成连续递增序列。
基础R实现(无依赖)
直接用ave()按分组做计算,不需要加载第三方包,代码最简洁:
dat$val <- ave(dat$val, dat$var, FUN = function(x) { # 定位组内非NA值的行位置 anchor_idx <- which(!is.na(x)) # 按当前行与锚点的位置差计算连续值 x[anchor_idx] + (seq_along(x) - anchor_idx) })
dplyr实现
如果习惯tidyverse语法,可以用分组变更的写法:
library(dplyr) dat <- dat %>% group_by(var) %>% mutate( val = val[!is.na(val)] + (row_number() - which(!is.na(val))) ) %>% ungroup()
运行以上任意一段代码,得到的结果都和期望输出完全一致。
内容的提问来源于stack exchange,提问作者erc
相关产品推荐
相关产品推荐

