【问题标题】:Make weight column based on site distance in R根据R中的站点距离制作权重列
【发布时间】:2021-02-22 07:59:28
【问题描述】:

抱歉,如果这是一个幼稚的问题,但我无法解决。我有一个数据框,其中包含名为site 的列及其坐标(longlat)。我想根据站点距离创建一个名为weight 的新列。

例如:

site <- c(1, 2, 3, 4, 5)
long <- c(119.5772, 123.7172, 126.4772, 122.7972, 122.3372)
lat <- c(-31.45806, -33.75806, -31.91806, -31.91806, -31.91806)

df <- data.frame(site, long, lat)

我想根据地理距离在数据框df 中添加一个weight 列。换句话说,我想要一个名为weight 的列,以便根据Ellipsoid 距离对站点进行加权。谢谢。

我想要的输出应该是:

df  
  site     long       lat weight
1    1 119.5772 -31.45806  0.955
2    2 123.7172 -33.75806  0.855
3    3 126.4772 -31.91806  0.654
4    4 122.7972 -31.91806  0.358
5    5 122.3372 -31.91806  0.254

注意:我在上面的权重列中输入了随机数。标准应该是最近的站点比远处的站点获得更多的权重。

【问题讨论】:

  • 基于longlat的图形距离。
  • 站点之间应该有距离。例如,site1 的距离应该通过它与所有其他站点的距离进行比较,并且对于所有站点都相同。之后,应计算权重并将其分配给新列。
  • 是的,它需要计算一个距离矩阵。并且权重标准应该是这样的,即最近的站点将获得更多的权重,而远处的站点将获得更少的权重。
  • 计算weight的公式/算法是什么?
  • @Wimpel 我不知道。这就是我在这里发布问题的原因。

标签: r arcgis sf sp weighted


【解决方案1】:

距离矩阵可以计算为

geosphere::distm(x = df[2:3])
> geosphere::distm(x = df[2:3])      
         [,1]     [,2]     [,3]      [,4]      [,5]
[1,]      0.0 464760.0 656073.1 309512.28 266596.37
[2,] 464760.0      0.0 329233.1 221489.49 241514.75
[3,] 656073.1 329233.1      0.0 348026.93 391525.30
[4,] 309512.3 221489.5 348026.9      0.00  43505.42
[5,] 266596.4 241514.7 391525.3  43505.42      0.00

现在根据您在下面的评论,您已经按照此策略计算了weight

m <- geosphere::distm(x = df[2:3])      
diag(m) <- NA
df$mean <- apply(m, 1, mean, na.rm = T)
df <- df[order(df$mean, decreasing = T),]
df$order <- c(1:nrow(df))
df$weight <- (df$order - min(df$order)/max(df$order)-min(df$order))
df

  site     long       lat     mean order weight
3    3 126.4772 -31.91806 431214.6     1   -0.2
1    1 119.5772 -31.45806 424235.4     2    0.8
2    2 123.7172 -33.75806 314249.3     3    1.8
5    5 122.3372 -31.91806 235785.5     4    2.8
4    4 122.7972 -31.91806 230633.5     5    3.8

在我看来,这可以通过这个来实现

library(dplyr)
df %>% mutate(order = 1 + n - dense_rank(apply(distm(x = df[2:3]), 1, FUN = function(x){sum(x)/(n-1)})),
         weight = order - (1 + 1/n))
  site     long       lat order weight
1    1 119.5772 -31.45806     2    0.8
2    2 123.7172 -33.75806     3    1.8
3    3 126.4772 -31.91806     1   -0.2
4    4 122.7972 -31.91806     5    3.8
5    5 122.3372 -31.91806     4    2.8

简单的逻辑是您的 min(df$order) 值将始终为 1,而 max(df$order) 将始终等于数据框中的行数。

【讨论】:

  • 谢谢。您可以对最近的权重最高的站点进行加权吗?
  • 非常感谢。我接受了你的回答。非常感谢。
  • 啊...实际上我的目标是对最近的站点给予最高的权重,对最远的站点给予最低的权重。可能我需要取平均距离,然后以最高权重获得最低距离。您可以将其设置为 0-1 范围,以便最高值为 1,最低值为 0.xx。
  • 我,谦虚地建议你用笔和纸来做这件事。对我来说,如果查看整个数据,就不会有最近站点或最远站点之类的东西。如果仅查看一行/站点,则这些站点每次都会不同。例如对于站点 1,站点 5 最近,但站点 3 最远。现在对于站点 2,这些值可能不同(分别为 4 和 1)。因此,至少不能按照这个标准计算权重。我认为你在这个逻辑的某个地方感到困惑。
  • 它对我有用。这是我用笔和纸做的。我没有使用df$weight &lt;- apply(m, 1, which.min) 中的最小值,而是使用了meanwdf$weight &lt;- apply(m, 1, mean, na.rm=T); wdf &lt;- wdf[order(wdf$weight, decreasing = T),]; wdf$weight2 &lt;- c(1:nrow(wdf)); wdf$weightF &lt;- (wdf$weight2 - min(wdf$weight2)/max(wdf$weight2)-min(wdf$weight2))
【解决方案2】:

这是一个部分答案..创建距离矩阵..

library( sf )

df %>% 
  st_as_sf( coords = c("long", "lat"), crs = 4326 ) %>%
  st_distance()

# Units: [m]
#           [,1]     [,2]     [,3]      [,4]      [,5]
# [1,]      0.0 464760.0 656073.1 309512.28 266596.37
# [2,] 464760.0      0.0 329233.1 221489.49 241514.75
# [3,] 656073.1 329233.1      0.0 348026.93 391525.30
# [4,] 309512.3 221489.5 348026.9      0.00  43505.42
# [5,] 266596.4 241514.7 391525.3  43505.42      0.00

如果你不知道如何计算重量,那么我不知道如何编程。

【讨论】:

    猜你喜欢
    • 2012-03-16
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多