根据R中的站点距离制作权重列
Make weight column based on site distance in R
抱歉,如果这是一个幼稚的问题,但我无法给出解决方案。我有一个数据框,其中包含名为 site
的列及其坐标(long
、lat
)。我想根据站点距离创建一个名为 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) 将始终等于数据框中的行数。
抱歉,如果这是一个幼稚的问题,但我无法给出解决方案。我有一个数据框,其中包含名为 site
的列及其坐标(long
、lat
)。我想根据站点距离创建一个名为 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) 将始终等于数据框中的行数。