R语言data.table两非零值中间0值的按行插值实现方法
R语言data.table按行插值夹在非零值之间的0的实现方案
实现思路
你需要替换的是左右相邻值均为正数的单个0值,针对4列年份的场景可以直接用data.table原生条件更新实现,运行效率高且无需额外依赖。
最简实现(适配你的当前场景)
首先加载依赖、构造测试数据:
library(data.table) df1 = data.table( ID = c("a1", "a2", "a3", "a4", "a5", "a6", "a7"), "string1" = c("x2", "g3", "n2", "m3", "2w", "ps2", "kg2"), "2018" = c(3,5,11,3,9,2,6), "2019" = c(3,5,0,0,1,4,0), "2020" = c(0,4,0,9,6,7,9), "2021" = c(4,0,3,8,5,4,6), "string2" = c("si", "q2", "oq", "mx", "ix", "p2", "2q"))
执行插值逻辑:
# 处理2019列:判断是否为0且左右(2018、2020)均为正数 df1[`2019` == 0 & `2018` > 0 & `2020` > 0, `2019` := (`2018` + `2020`)/2] # 处理2020列:判断是否为0且左右(2019、2021)均为正数 df1[`2019` > 0 & `2020` == 0 & `2021` > 0, `2020` := (`2019` + `2021`)/2]
运行后输出的df1和你给出的期望结果完全一致。
通用实现(适配更多年份列的场景)
如果后续年份列数量增加,可以用按行应用自定义函数的方案,通用性更强:
year_cols <- as.character(2018:2021) # 自定义插值函数 interpolate_mid_zero <- function(x) { n <- length(x) for (i in 2:(n-1)) { if (x[i] == 0 && x[i-1] > 0 && x[i+1] > 0) { x[i] <- (x[i-1] + x[i+1])/2 } } return(x) } # 按行应用到所有年份列 df1[, (year_cols) := as.list(interpolate_mid_zero(unlist(.SD))), by = 1:nrow(df1), .SDcols = year_cols]
内容的提问来源于stack exchange,提问作者fjurt
相关产品推荐
相关产品推荐

