如何用R的ave()函数生成基于前两年与当前年的加权数据列
R语言ave()函数加权规则修正求助
我之前在R语言中用ave()函数实现了基于**当前年(0.5)、前一年(0.25)、后一年(0.25)**的加权数据列,代码运行正常。现在需要修改加权规则为:0.25当前年 + 0.5前一年 + 0.25*前前年(例如202021行计算为0.25*2350 + 0.5*2100 + 0.25*2550)。我尝试了多种写法均失败,现附上原始代码、测试数据及尝试的错误代码,请求帮助修正。
原始代码
data$smoothingOO <- ave(x = data$OO_EST, data$Area_Code, # grouping FUN = \(x) { # first row y1 <- x[1L] * .75 + x[2L] * .25 # last row yl <- x[length(x)] * .75 + x[length(x) - 1L] * .25 # "inner rows" y <- x * .5 + .25 * c(0L, x[-length(x)]) + .25 * c(x[-1L], 0) # combine first, inner minus first and last, and last row c(y1, y[-c(1L, length(y))], yl) })
测试数据
data <- structure(list( Year_Code = c(201112, 201213, 201314, 201415, 201516, 201617, 201718, 201819, 201920, 202021, 201112, 201213, 201314, 201415, 201516), Area_Code = c(512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 333, 333, 333, 333, 333), Area_ItemName_ENG = c(" Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey ", " Isle of Anglesey "), OO_EST = c(2000, 2500, 2200, 2400, 2250, 2300, 2700, 2550, 2100, 2350, 2000, 2500, 2200, 2400, 2250)), row.names = c(NA, -15L), class = "data.frame")
尝试的错误写法
# 错误写法1 y <- x * .25 + .5 * c(0L, x[-length(x)]) + .25 * c(0L, x[-length(x - 1L)]) # 错误写法2 y <- x * .25 + .5 * c(0L, x[-length(x)]) + .25 * c(0L, x[-length(x) - 1L ]) # 错误写法3 y <- x * .25 + .5 * c(0L, x[-length(x)]) + .25 * c(1L, x[-length(x)]) # 错误写法4 y <- x * .25 + .5 * c(0L, x[-length(x)]) + .25 * c(0L, x[-length(2x)])
修正后的代码及说明
data$smoothingOO <- ave(x = data$OO_EST, data$Area_Code, # grouping FUN = \(x) { n <- length(x) # 构造前一年向量:首位补0,对应每个位置的前一年数据 prev_year <- c(0, x[-n]) # 构造前前年向量:前两位补0,对应每个位置的前前年数据 prev_prev_year <- c(0, 0, x[-(n-1):-n]) # 基础加权计算 y <- 0.25 * x + 0.5 * prev_year + 0.25 * prev_prev_year # 处理第一行:无前后年份,沿用原逻辑分配权重 if(n >= 2) { y[1] <- x[1] * 0.75 + x[2] * 0.25 } # 处理第二行:无前前年,调整权重分配给当前年和前一年 if(n >= 3) { y[2] <- 0.25 * x[2] + 0.75 * x[1] } y })
关键修正点:
- 前前年向量构造:用
c(0, 0, x[-(n-1):-n])生成与原向量长度一致的序列,前两位补0,后续对应原数据的前n-2个值,完美匹配"前前年"的位置关系。 - 首尾行适配:第一行因无历史数据,沿用原代码的加权逻辑;第二行无前前年数据,将原前前年的权重分配给前一年,保证权重总和为1。
- 最后一行无需特殊处理:新规则下最后一行有前一年和前前年数据,可直接纳入基础计算。
以测试数据中202021行(Area_Code=512的第10行)为例,计算结果为0.25*2350 + 0.5*2100 + 0.25*2550 = 2275,符合预期。
内容的提问来源于stack exchange,提问作者Voycey98
相关产品推荐
相关产品推荐

