我正在尝试查看中每个 center点中有多少个center,但这是目前在for循环中完成的。如果可以矢量化的话会有可能吗?下面是一个可以复制的片段。谢谢。
require(geosphere)
centers <- as.data.frame(matrix(rnorm(10, mean = 40, sd = .5), ncol = 2, byrow = TRUE))
points <- matrix(rnorm(100, mean = 40, sd = 1), ncol = 2, byrow = TRUE)
for(i in 1:dim(centers)[1]){
# Calculate number of points that are 50 km within every center point
centers[i,3] <- sum(geosphere::distHaversine(points,
centers[i,c(1:2)]) /
1000 < 50, na.rm = TRUE)
}发布于 2021-01-27 05:22:56
您可以将split与row和sapply一起使用,然后再使用colSums
library(geosphere)
centers$res <- colSums(
sapply(split(as.matrix(centers[, 1:2]), row(centers)[, 1:2]),
distHaversine, p1 = points) / 1000 < 50, na.rm = TRUE)它给出了同样的结论:
# compute the old result to compare with
for(i in 1:dim(centers)[1])
centers[i,4] <- sum(geosphere::distHaversine(points,
centers[i,c(1:2)]) /
1000 < 50, na.rm = TRUE)
# gives the same
all.equal(centers$res, centers[, 4])
#R> [1] TRUE另一种可能的选择是:
dists <- tapply(as.matrix(centers[, 1:2]), row(centers[, 1:2]),
distHaversine, p1 = points)
centers$res <- colSums(simplify2array(dists) / 1000 < 50, na.rm = TRUE)或者使用匿名函数。这就像Ronak Shah的答案,但是有了tapply
centers$res <- c(tapply(
as.matrix(centers[, 1:2]), row(centers[, 1:2]), function(x)
sum(distHaversine(points, x) / 1000 < 50, na.rm = TRUE)))发布于 2021-01-27 03:24:25
如果函数一次只能处理一个点,我不认为它能够真正地向量化。您可以将for循环替换为sapply,并查看性能是否有任何改善。
library(geosphere)
centers$total <- sapply(seq(nrow(centers)), function(i) {
sum(distHaversine(points, centers[i,]) /1000 < 50, na.rm = TRUE)
}) https://stackoverflow.com/questions/65910935
复制相似问题