在R语言中使用Simpson法则计算AUC:适配偶数长度向量
问题
我需要通过一组实验值计算曲线下面积(AUC),基于辛普森法则编写了一个AUC近似计算函数,但该函数仅能处理奇数长度的输入向量。想修改代码,让它在输入为偶数长度时,自动用梯形法计算最后一段的面积并加入总AUC中。
原函数代码:
AUC <- function(x, h=1){ # AUC function computes the Area Under the Curve of a time serie using # the Simpson's Rule (numerical method). # Arguments # x: (vector) time serie values # h: (int) temporal resolution of the time serie. default h=1 n = length(x)-1 xValues = seq(from=1, to=n, by=2) sum <- list() for(i in 1:length(xValues)){ n_sub <- xValues[[i]]-1 n <- xValues[[i]] n_add <- xValues[[i]]+1 v1 <- x[[n_sub+1]] v2 <- x[[n+1]] v3 <- x[[n_add+1]] s <- (h/3)*(v1+4*v2+v3) sum <- append(sum, s) } sum <- unlist(sum) auc <- sum(sum) return(auc) }
数据示例:
smoothed = c(0.3,0.317,0.379,0.452,0.519,0.573,0.61,0.629,0.628,0.613,0.587,0.556,0.521, 0.485,0.448,0.411,0.363,0.317,0.273,0.227,0.185,0.148,0.12,0.103,0.093,0.086, 0.082,0.079,0.076,0.071,0.066,0.059,0.053,0.051,0.052,0.057,0.067,0.081,0.103, 0.129,0.165,0.209,0.252,0.292,0.328,0.363,0.398,0.431,0.459,0.479,0.491,0.494, 0.488,0.475,0.457,0.43,0.397,0.357,0.316,0.285,0.254,0.227,0.206,0.189,0.181, 0.171,0.157,0.151,0.162,0.192,0.239)
解决方案
核心思路是先判断输入向量的长度:
- 如果是奇数,直接用原辛普森法则计算全部区间;
- 如果是偶数,先用辛普森法则处理前
length(x)-1个点(即奇数个点,对应偶数个区间),最后用梯形法计算最后两个点之间的面积,加到总AUC中。
修改后的函数代码:
AUC <- function(x, h=1){ # 基于辛普森法则计算时间序列的曲线下面积(AUC),支持偶数长度输入 # 参数说明: # x: 时间序列数值向量 # h: 时间序列的时间分辨率,默认值为1 len_x <- length(x) auc_total <- 0 # 处理奇数长度的情况 if(len_x %% 2 == 1){ n <- len_x - 1 xValues <- seq(from=1, to=n, by=2) sum_simpson <- numeric(length(xValues)) for(i in seq_along(xValues)){ idx <- xValues[i] v1 <- x[idx] v2 <- x[idx+1] v3 <- x[idx+2] sum_simpson[i] <- (h/3)*(v1 + 4*v2 + v3) } auc_total <- sum(sum_simpson) } else { # 偶数长度:先处理前len_x-1个点(奇数个),再用梯形法加最后一段 # 辛普森部分 n <- len_x - 2 xValues <- seq(from=1, to=n, by=2) sum_simpson <- numeric(length(xValues)) for(i in seq_along(xValues)){ idx <- xValues[i] v1 <- x[idx] v2 <- x[idx+1] v3 <- x[idx+2] sum_simpson[i] <- (h/3)*(v1 + 4*v2 + v3) } auc_total <- sum(sum_simpson) # 梯形法处理最后一段 last_area <- h * (x[len_x-1] + x[len_x]) / 2 auc_total <- auc_total + last_area } return(auc_total) }
代码说明
- 奇偶判断:通过
len_x %% 2 == 1快速判断输入向量长度的奇偶性; - 效率优化:用
numeric()预分配内存替代列表追加操作,提升计算效率; - 梯形补全:偶数长度时,最后一段区间使用梯形面积公式
h*(x_n-1 + x_n)/2计算,保证整体精度。
测试验证
用提供的smoothed向量测试:
# 查看向量长度:71(奇数) length(smoothed) # 计算AUC AUC(smoothed) # 输出结果:约21.74(具体值可运行代码验证)
构造偶数长度向量测试:
test_vec <- c(1,2,3,4) AUC(test_vec) # 计算逻辑:辛普森处理前3个点(1,2,3)得(1/3)*(1+4*2+3)=10/3≈3.333,梯形处理最后一段(3,4)得(3+4)/2=3.5,总AUC≈6.833
内容的提问来源于stack exchange,提问作者sermomon
相关产品推荐
相关产品推荐

