根据R中的站点距离制作权重列

Make weight column based on site distance in R

抱歉,如果这是一个幼稚的问题,但我无法给出解决方案。我有一个数据框,其中包含名为 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

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

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

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

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

距离矩阵可以计算为

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) 将始终等于数据框中的行数。