我正在编写一个for循环来计算分子,该分子是较大公式的一部分。我使用了for循环,但是要花很多时间才能计算出来。有什么更好的方法可以做到这一点。
city
是具有以下列的数据框:pop, not.white, pct.not.white
n <- nrow(city)
numerator = 0
for(i in 1:n) {
ti <- city$pop[i]
pi<- city$pct.not.white[i]
for(j in 1:n) {
tj <- city$pop[j]
pj <- city$pct.not.white[j]
numerator = numerator + (ti * tj) * abs(pi -pj)
}
}
答案 0 :(得分:4)
使用以下玩具数据进行结果验证。
set.seed(0)
city <- data.frame(pop = runif(101), pct.not.white = runif(101))
最明显的“向量化”:
# n <- nrow(city)
titj <- tcrossprod(city$pop)
pipj <- outer(city$pct.not.white, city$pct.not.white, "-")
numerator <- sum(titj * abs(pipj))
如果n > 5000
可能会出现内存问题。
一个聪明的解决方法(利用对称性;更有效的内存“矢量化”):
## see https://stackoverflow.com/a/52086291/4891738 for function: tri_ind
n <- nrow(city)
ij <- tri_ind(n, lower = TRUE, diag = FALSE)
titj <- city$pop[ij$i] * city$pop[ij$j]
pipj <- abs(city$pct.not.white[ij$i] - city$pct.not.white[ij$j])
numerator <- 2 * crossprod(titj, pipj)[1]
最终的解决方案是编写C / C ++循环,我将不再展示。