我正在尝试将应用函数隐藏到嵌套循环中,以便在R之外的软件中使用。我编写的循环看起来很相似,但是返回的值与应用函数略有不同。
我一直尝试调整索引,但仍然无法返回相同的值。
require(MASS)
# set up grid
B <- 5
co <- seq(0, 1, length=B)
Z <- cbind(rep(co, each=B), rep(co, times=B))
# long hand euclidean distance
x <- Z[,1]
y <- Z[,2]
d <- matrix(NA, nrow = nrow(Z), ncol = nrow(Z))
N <- nrow(Z)
for(i in 1:N){
for(j in 1:N){
d[i,j] <- sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]))
}
}
# generate a value for each pixel
cov <- MASS::mvrnorm(1, mu = rep(0, nrow(Z)), Sigma = exp(-d/0.25))
# calculate weights of each pixel
# apply
applyW <- apply(d, 1, function(x) {
w0 <- exp(-x^2 / (2*0.3 * 0.3))
w0[which.min(x)] <- 0
w <- w0/sum(w0)
sum(cov * w)
})
# 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)){
for(j in 1:ncol(d)){
w0[i, j] <- exp(-(d[i,j] * d[i,j]) / (2 * 0.3 * 0.3))
w0[which.min(w0)] <- 0
}
w[i, ] <- w0[i ,]/sum(w0[i,])
loopW[i] <- sum(cov * w[i,])
}
# check the values
cbind(applyW, loopW)
我期望applyW和loopW是相同的值,但是我找不到。值相似,但不相同。这是一个舍入错误还是代码中有错误?
答案 0 :(得分:1)
我还没有花时间来确切地了解您要完成的工作,但是代码的这两部分在执行方面并不匹配:
在您的申请中:
w0[which.min(x)] <- 0
这里w0
是一个向量(即一行),您正在用0替换该向量中的最小值。按照apply(MARGIN = 1)
分别对每一行进行此操作。
但是,在循环中您有:
w0[which.min(w0)] <- 0
这里w0
是一个矩阵,每次移动到下一个矩阵元素时,代码中w0[which.min(w0)] <- 0
所在的位置连续用0替换最小值(即,不按行在您的apply()
中。
如果将此行移到内循环之外并进行一些调整以匹配apply()
,则会得到相同的值:
require(MASS)
# set up grid
B <- 5
co <- seq(0, 1, length=B)
Z <- cbind(rep(co, each=B), rep(co, times=B))
# long hand euclidean distance
x <- Z[,1]
y <- Z[,2]
d <- matrix(NA, nrow = nrow(Z), ncol = nrow(Z))
N <- nrow(Z)
for(i in 1:N){
for(j in 1:N){
d[i,j] <- sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]))
}
}
# generate a value for each pixel
cov <- MASS::mvrnorm(1, mu = rep(0, nrow(Z)), Sigma = exp(-d/0.25))
# calculate weights of each pixel
# apply
applyW <- apply(d, 1, function(x) {
w0 <- exp(-x^2 / (2*0.3 * 0.3))
w0[which.min(x)] <- 0
w <- w0/sum(w0)
sum(cov * w)
})
# 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)){
for(j in 1:ncol(d)){
w0[i, j] <- exp(-(d[i,j] * d[i,j]) / (2 * 0.3 * 0.3))
#w0[which.min(w0)] <- 0 move this outside inner loop
}
w0[i, which.min(d[i, ])] <- 0 # and make some tweaks to match the apply
w[i, ] <- w0[i ,]/sum(w0[i,])
loopW[i] <- sum(cov * w[i,])
}
# check the values
output <- cbind(applyW, loopW)
output <- cbind(output, "dif" = output[, "applyW"] - output[, "loopW"])
output
产生:
applyW loopW dif
[1,] 0.62023939 0.62023939 0
[2,] 0.45082535 0.45082535 0
[3,] 0.07066739 0.07066739 0
[4,] 0.01518537 0.01518537 0
[5,] 0.13383600 0.13383600 0
[6,] 0.52896297 0.52896297 0
[7,] 0.38474014 0.38474014 0
[8,] 0.23321748 0.23321748 0
[9,] 0.07092092 0.07092092 0
[10,] -0.04388823 -0.04388823 0
[11,] 0.46926149 0.46926149 0
[12,] 0.39166724 0.39166724 0
[13,] 0.12309979 0.12309979 0
[14,] -0.04778011 -0.04778011 0
[15,] 0.10359100 0.10359100 0
[16,] 0.41273927 0.41273927 0
[17,] 0.33122926 0.33122926 0
[18,] -0.10115094 -0.10115094 0
[19,] -0.15051985 -0.15051985 0
[20,] -0.23035539 -0.23035539 0
[21,] 0.37065262 0.37065262 0
[22,] -0.24497145 -0.24497145 0
[23,] -0.04993695 -0.04993695 0
[24,] -0.24990339 -0.24990339 0
[25,] -0.27183745 -0.27183745 0