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

R语言基于游程编码按条件替换向量值的简洁base R方案

单次游程编码实现0值批量替换

需求说明

持有若干仅包含-1、0、1三类取值的不等长数值向量,其中0占绝大多数,需同时满足以下两个规则,将符合条件的0替换为相邻非零值:

  • 规则1:连续出现的0的长度小于3
  • 规则2:该段连续0的左右两侧为相同的非零值

示例:序列1,1,1,1,0,1,1中的单个0需替换为1;序列1,1,-1,1,0,-1,-1中的0因两侧非零值不同,保持原值不变。
原有实现分两次执行游程编码,分别处理替换为1、替换为-1的场景,代码冗余,尝试合并逻辑时R抛出报错,需要更优雅紧凑的base R原生实现,无需对数据进行两次迭代处理。

测试数据

测试输入向量

x <- c(1,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,0,-1,0,0,0,0,1,1,0,0,0,1)
y <- c(0,0,-1,0,-1,0,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,0,1,0,0,0)
z <- c(0,0,0,0,1,0,1,0,1,0,1,0,-1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,-1,0,1,0,-1,0,1,0,0,0,0,0,0,0,0,0)
a <- c(0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,-1,0,0,0,0,0,0)

预期输出

x_desired <- c(1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1)
y_desired <- c(0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0)
z_desired <- c(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)
a_desired <- c(0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0)

原有冗余实现

substitute_plus_and_minus <- function(x){
    
  # create the run length encoding
  mod_rle <- rle(x)
  # create an index of 0s to be changed for 1s
  one_substitute <- mod_rle$lengths <3 &
    mod_rle$values == 0 &
    c(utils::tail(mod_rle$values, -1) == 1, FALSE) &
    c(FALSE, utils::head(mod_rle$values, -1) == 1)
  # set the values to 1
  mod_rle$values[one_substitute] <- 1
  # recreate the original vector
  x <- inverse.rle(mod_rle)
  
  # create the run length encoding
  mod_rle <- rle(x)
  # create an index of 0s to be changed for -1s
  minus_one_substitute <- mod_rle$lengths <3 &
    mod_rle$values == 0 &
    c(utils::tail(mod_rle$values, -1) == -1, FALSE) &
    c(FALSE, utils::head(mod_rle$values, -1) == -1)
  # set the values to -1
  mod_rle$values[minus_one_substitute] <- -1
  # recreate the original vector
  x <- inverse.rle(mod_rle)
  
  return(x)
  
}

单次游程编码优化实现

不需要分1、-1两次处理,只需要做1次游程编码,统一判断所有中间位置的0游程是否满足替换条件,直接替换为两侧相同的非零值即可:

substitute_single_pass <- function(x) {
  rx <- rle(x)
  run_len <- length(rx$values)
  # 游程总数小于3时不存在夹在两个非零值中间的0段,直接返回原向量
  if (run_len >= 3) {
    # 预存每个游程左右相邻的取值
    left_vals  <- c(NA, rx$values[-run_len])
    right_vals <- c(rx$values[-1], NA)
    # 定位所有满足替换条件的0游程
    replace_pos <- which(
      rx$values == 0 &
      rx$lengths < 3 &
      !is.na(left_vals) & !is.na(right_vals) &
      left_vals == right_vals &
      left_vals != 0
    )
    # 批量替换为两侧相同的非零值
    rx$values[replace_pos] <- left_vals[replace_pos]
  }
  inverse.rle(rx)
}

效果验证

对所有测试用例执行校验,结果完全匹配预期输出:

all(
  identical(substitute_single_pass(x), x_desired),
  identical(substitute_single_pass(y), y_desired),
  identical(substitute_single_pass(z), z_desired),
  identical(substitute_single_pass(a), a_desired)
)
# [1] TRUE

方案优势

  • 仅执行1次游程编码、1次逆解码,无重复迭代处理
  • 逻辑统一,不需要分别针对1、-1写分支判断
  • 自动跳过首尾位置的0段(无两侧邻居,不满足替换条件)
  • 完全基于base R原生函数,无第三方包依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:33:20