R中按日期分plot实现Nmin缺失值的linear interpolation插补
按分组线性插值补全土壤Nmin缺失值方案
完全可以通过现有函数实现需求,不需要手动编写逐点计算的逻辑,核心是使用支持自定义x轴间距的线性插值函数,配合分组操作即可实现按plot独立计算、自动匹配采样日期间隔的插补。
推荐实现方法
最简便的方案是用zoo包中的na.approx()函数完成线性插值:该函数支持指定时间变量作为插值的x轴,会自动根据相邻观测点的实际时间差计算线性变化梯度,完全匹配两次采样间隔内Nmin呈线性变化的前提假设,不会默认按等间距采样计算结果。配合dplyr包的分组操作,即可快速实现按plot分组的插补。
实现代码
# 加载所需包 library(dplyr) library(zoo) # 构造示例数据(修正了原代码中日期转换的格式参数错误,原参数与实际日期格式不匹配会导致日期转换为NA) df <- data.frame(plot= c(1,2,3,4,5,6,7,8,9,10), date = c("2020-10-01", "2020-10-01","2020-10-01","2020-10-01","2020-10-01","2020-10-01","2020-10-01","2020-10-01","2020-10-01","2020-10-01", "2020-10-08", "2020-10-08","2020-10-08","2020-10-08","2020-10-08","2020-10-08","2020-10-08","2020-10-08","2020-10-08","2020-10-08", "2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29","2020-10-29", "2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05","2020-11-05"), Nmin = c(100, 120, 50, 60, 70, 80, 100, 70, 30, 50, 90, 130, 60, 60, 60, 90, 105, 60, 25, 40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 50, 170, 100, 60, 20, 130, 125, 20, 5, 0)) df$date <- as.Date(df$date, format="%Y-%m-%d") df$Nmin <- as.numeric(df$Nmin) # 按plot分组插值 df_imputed <- df %>% group_by(plot) %>% # 每个组内按采样日期升序排列,保证插值顺序正确 arrange(date, .by_group = TRUE) %>% mutate( # 指定date为x轴,按实际时间间隔计算线性插补值 Nmin = na.approx(Nmin, x = date, na.rm = FALSE) ) %>% ungroup()
注意事项
- 插值前必须保证每个plot组内的记录按日期升序排列,否则会出现计算错误
na.approx()默认对序列首尾位置的缺失值保留NA,如果需要对首尾缺失值做外插,可以调整函数的rule参数- 如果不想使用dplyr,也可以用基础R的
ave()函数配合na.approx()实现分组插值,不需要额外加载数据操作包
以示例数据中plot1的计算结果为例:2020-10-08的Nmin为90,2020-11-05的Nmin为50,两个日期间隔28天,Nmin总变化量为-40,日均变化量约为-1.4286;2020-10-29距离2020-10-08间隔21天,插补值为90 + (-1.4286)*21 = 60,完全符合线性变化的计算逻辑。
内容的提问来源于stack exchange,提问作者Greenfee
相关产品推荐
相关产品推荐

