为何R中apply函数与嵌套循环返回值存在差异?代码排查
问题分析:apply转嵌套循环结果不一致的原因及修正
你遇到的不是舍入误差,而是循环逻辑里的关键错误,导致了结果差异。咱们来拆解一下问题:
先看apply版本的核心逻辑
apply是对d的每一行独立处理,步骤是:
- 对当前行的所有距离值计算
w0 = exp(-x²/(2*0.3²)) - 找到当前行的最小值(也就是对角线位置的0,因为距离矩阵里
d[i,i]永远是0),把对应的w0设为0 - 归一化
w0得到权重w,再和cov向量相乘求和
你的循环代码的错误点
在你的嵌套循环里,你把w0[which.min(w0)] <- 0放在了内层的j循环里——这意味着每处理一个列j,就会在整个w0矩阵里找最小值并设为0,而不是针对当前正在处理的第i行。
举个例子:当处理第1行的j=2时,which.min(w0)会扫描整个已经填充了部分值的w0矩阵,可能会修改其他行的元素,完全打乱了每一行独立处理的逻辑,这就是结果不一致的根源。
修正后的循环代码
把“设0”的操作移到内层循环之后,只针对当前处理的第i行操作:
# 修正后的for loop approach w0 <- matrix(NA, ncol = ncol(d), nrow = nrow(d)) w <- matrix(NA, ncol = ncol(d), nrow = nrow(d)) loopW <- c() for(i in 1:nrow(d)){ # 先计算当前行所有的w0值 for(j in 1:ncol(d)){ w0[i, j] <- exp(-(d[i,j]^2) / (2 * 0.3^2)) } # 仅对当前行的最小值位置设为0(也就是当前行的对角线元素) w0[i, which.min(w0[i,])] <- 0 # 归一化当前行的权重 w[i, ] <- w0[i ,]/sum(w0[i,]) # 计算加权求和值 loopW[i] <- sum(cov * w[i,]) }
额外优化
因为d是对称的距离矩阵,每一行的最小值必然是对角线位置d[i,i](值为0),所以可以直接写w0[i,i] <- 0,省去which.min的计算,结果完全一致,还能提高效率:
# 优化后的设0步骤 w0[i,i] <- 0
验证结果
运行修正后的代码后,执行cbind(applyW, loopW)就能看到两个向量完全一致,用all.equal(applyW, loopW)会返回TRUE(极微小的浮点误差属于正常现象,不会影响结果一致性)。
内容的提问来源于stack exchange,提问作者Brent Pease
相关产品推荐
相关产品推荐

