首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >For Loop使用geosphere软件包计算R中的欧几里德距离

For Loop使用geosphere软件包计算R中的欧几里德距离
EN

Stack Overflow用户
提问于 2020-12-08 02:23:12
回答 1查看 75关注 0票数 0

我已经成功地遵循了Error in data.frame(..., check.names = FALSE) : Looping For的说明,使用geosphere包计算了从原点到目的地的距离。现在,当我想对不同的数据集执行相同的操作时,我发现了新的麻烦。我有两个数据集,如下所示:

代码语言:javascript
复制
ORIGIN (MASTERDATA)
NO xcoord    ycoord
1  109.6663  -6.897970
2  109.6584  -6.897511
3  109.6519  -6.893822
4  109.6586  -6.896936
5  109.6651  -6.897484

DESTINATON (SMP)
NO x_SMP    y_SMP
1  109.6652  -6.898086
2  109.6501  -6.910931
3  109.6579  -6.891705
4  109.6579  -6.891705
5  109.6579  -6.891705

从上面的两个数据集,我想计算每一行的距离。原始数据集的第一行将与目标数据集的第一行相遇,思路如下:

代码语言:javascript
复制
ORIGIN   DESTINATION
Row 1 -> Row 1 : Distance 1
Row 2 -> Row 2 : Distance 2
Row 3 -> Row 3 : Distance 3
Row 4 -> Row 4 : Distance 4
Row 5 -> Row 5 : DIstance 5

为了实现这些目标,我使用geosphere包操作For Loop来计算每一行的距离,语法如下:

代码语言:javascript
复制
library(geosphere)
n = nrow(masterdata)
    datalist = list()

for (i in 1:n) {
  # ... make some data
  dat <- distm(c(masterdata$xcoord[i], masterdata$ycoord[i]), c(masterdata$x_SMP[i], masterdata$y_SMP[i]), fun = distHaversine)
  dat$i <- i 
  datalist[[i]] <- dat
}

big_data = do.call(cbind, datalist)

使用这种语法,我想将循环操作的结果附加到数据帧中。执行后,我发现结果并不像我期望的那样。数据帧应该有n行。结果,我只有1行。

谢谢

EN

回答 1

Stack Overflow用户

发布于 2020-12-08 03:51:55

对于您已有的代码,最简单的解决方案就是在for循环中去掉dat$i,并在将向量big_data添加到masterdata之前将其转置。

代码语言:javascript
复制
NO = c(1,2,3,4,5)
xcoord = c(109.6663, 109.6584, 109.6519, 109.6586, 109.6651)
ycoord = c(-6.897970, -6.897511, -6.893822, -6.896936, -6.897484)
x_SMP = c(109.6652, 109.6501, 109.6579, 109.6579, 109.6579)
y_SMP = c(-6.898086, -6.910931, -6.891705, -6.891705, -6.891705)

masterdata = data.frame("NO" = NO, "xcoord" = xcoord, "ycoord" = ycoord, "x_SMP" = x_SMP, "y_SMP" = y_SMP)

library(geosphere)
n = nrow(masterdata)
datalist = list()

for (i in 1:n) {
  # ... make some data
  dat <- distm(c(masterdata$xcoord[i], masterdata$ycoord[i]), c(masterdata$x_SMP[i], masterdata$y_SMP[i]), fun = distHaversine)
  datalist[[i]] <- dat
}

big_data = do.call(cbind, datalist)
masterdata['distance'] = t(big_data)

在此期间,我会看看是否能找到更优雅的解决方案。

*已编辑

我不知道为什么我在回答之前没有多花两分钟的时间(大脑今天有点慢),但是可以通过执行以下操作来向量化您的代码

代码语言:javascript
复制
masterdata['distance'] = distHaversine(masterdata[c("xcoord", "ycoord")], 
                                       masterdata[c("x_SMP", "y_SMP")])

这样,您就不需要for循环了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65187272

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档