R语言如何用foreach实现夹在1之间长度小于3的连续0替换为1
R语言使用foreach实现序列替换需求
实现代码
# 加载所需包 library(foreach) # 构造示例数据 dt = data.frame(input = c(0,0,1,1,0,0,1,0,0,0,1,1,1,0,1)) # 提取input列的游程编码(连续相同值的长度与对应值) rle_res <- rle(dt$input) n_runs <- length(rle_res$lengths) # foreach遍历每个游程段处理后拼接为完整序列 dt$output <- foreach(i = 1:n_runs, .combine = 'c') %do% { run_val <- rle_res$values[i] run_len <- rle_res$lengths[i] # 原值为1直接保留 if (run_val == 1 %in% TRUE) { return(rep(1, run_len)) } # 遇到NA直接保留不处理 if (is.na(run_val)) { return(rep(NA, run_len)) } # 序列开头/结尾的0直接保留 if (i == 1 || i == n_runs) { return(rep(0, run_len)) } # 夹在两个1之间、连续长度小于3的0替换为1 if (rle_res$values[i-1] == 1 && rle_res$values[i+1] == 1 && run_len < 3) { return(rep(1, run_len)) } # 其余情况保留原0值 return(rep(0, run_len)) }
打印dt即可得到和要求完全一致的output结果。
大样本提速方案(可选)
如果数据量极大,可开启foreach并行执行进一步提升效率:
library(doParallel) # 注册并行集群,核心数可根据自身CPU配置调整 cl <- makeCluster(2) registerDoParallel(cl) # 将foreach的%do%替换为%dopar%即可并行执行 dt$output <- foreach(i = 1:n_runs, .combine = 'c') %dopar% { # 内部处理逻辑和串行版本完全一致 run_val <- rle_res$values[i] run_len <- rle_res$lengths[i] if (run_val == 1 %in% TRUE) return(rep(1, run_len)) if (is.na(run_val)) return(rep(NA, run_len)) if (i == 1 || i == n_runs) return(rep(0, run_len)) if (rle_res$values[i-1] == 1 && rle_res$values[i+1] == 1 && run_len < 3) return(rep(1, run_len)) return(rep(0, run_len)) } # 处理完成后关闭集群释放资源 stopCluster(cl)
内容的提问来源于stack exchange,提问作者yi-ting Fang
相关产品推荐
相关产品推荐

