我是R的新手,目前正在使用字段包中的rdist.earth()函数来计算坐标对之间的距离。我的问题是我的数据集非常大,几乎不可能运行该函数。我目前正在运行以下代码。
distance.matrix <- round(5280 * rdist.earth(x, y, miles = TRUE))
x数据帧有~1040000行,y有~1200。 我必须在服务器上运行它以使其工作,并且它仍然需要很长时间来计算。返回的距离矩阵大约为8 gb,几乎无法使用。
有没有办法对rdist.earth()或其他策略进行矢量化,以便我可以更有效地运行它?
答案 0 :(得分:2)
有一种矢量化功能的方法:
来自同一rdist.earth.vec
包的 fields
计算一个输入位置的相应元素之间成对的大圆距离的向量。
我也遇到了类似的问题,尽管没有那么多的位置对。
在2400 * 2400位置矩阵中,这对我有用。
我在一个数据帧(?combn()
)中将所有位置组合成双对,然后称为rdist.earth.vec
。
dyadic$GCD <- rdist.earth.vec(x1 =dyadic[,c("lon_orig","lat_orig")],
x2 =dyadic[,c("lon_dest","lat_dest")],
miles = FALSE)
眨眼就完成了对2.M +行的计算。
我希望这对某人有帮助。
答案 1 :(得分:0)
关于无法使用生成的矩阵,您无能为力。这是一个巨大的密集矩阵。您可以通过存储一些结果而不是重新计算和使用tcrossprod来加速rdist.earth函数:
library(fields)
rdist.earth2 <- function(x1, x2, miles = TRUE, R = NULL){
if (is.null(R)) {
if (miles)
R <- 3963.34
else R <- 6378.388
}
x1 <- x1 / 180
x2 <- x2 / 180
x1cs <- cbind(cospi(x1), sinpi(x1))
x2cs <- cbind(cospi(x2), sinpi(x2))
pp <- tcrossprod(cbind(x1cs[,1] * x1cs[,2], x1cs[,2] * x1cs[,3], x1cs[,4]),
cbind(x2cs[,1] * x2cs[,2], x2cs[,2] * x2cs[,3], x2cs[,4]))
pp <- pmin(pmax(-1, pp), 1)
matrix(R * acos(pp), nrow = nrow(x1), ncol = nrow(x2))
}
rlat <- function(n) runif(n, -90, 90)
rlong <- function(n) runif(n, -180, 180)
rlatlong <- function(n) cbind(rlong(n), rlat(n))
x1 <- rlatlong(1000)
x2 <- rlatlong(1000)
system.time(ans1 <- rdist.earth(x1, x2))
system.time(ans2 <- rdist.earth2(x1, x2))
identical(all.equal(ans1, ans2), TRUE)
我的速度提高了30%,而且内存效率似乎更高。您也可以将其拆分并尝试并行执行。
library(iterator)
library(foreach)
ans3 <- foreach(b = iter(x1, by = 'row', chunksize = 100000L ), .combine='rbind') %do% rdist.earth2(b, x2)
identical(all.equal(ans1, ans3), TRUE)
您必须注册并行后端并将%do%替换为%dopar%。这对速度没有多大帮助,但它可能让你在你的机器而不是服务器上进行,具体取决于你有多少内存。我可以在我的机器上用16 Gb RAM做1000000 * 1000。