1

我正在帮助为三年级课程组建一个空间 R 实验室,其中一项任务将是确定一个与一组多个其他站点最近(即平均最短距离)的特定站点。

我有一个距离矩阵dist_m,我使用gdistance::costDistance它生成的看起来像这样:

# Sample data
m <- matrix(c(2, 1, 8, 5,
              7, 6, 3, 4,
              9, 3, 2, 8,
              1, 3, 7, 4),
            nrow  = 4,
            ncol  = 4,
            byrow = TRUE)

# Sample distance matrix
dist_m <- dist(m)

dist_m打印时的样子:

          1         2         3
2  8.717798
3  9.899495  5.477226
4  2.645751  7.810250 10.246951

期望的输出:从这个 dist 我希望能够识别具有最低平均距离的索引值( 、 或12。在此示例中,它将是 index ,其平均距离为。理想情况下,我也希望返回平均距离()。3446.906.90

我可以通过执行以下操作找到单个索引的平均距离:

# Convert distance matrix to matrix
m = as.matrix(dist_m)

# Set diagonals and upper triangle to NA
m[upper.tri(m)] = NA
m[m == 0] = NA

# Calculate mean for index
mean(c(m[4,], m[,4]), na.rm = TRUE)

但是,理想情况下,我想要一个解决方案,直接识别具有最小平均距离的索引,而不是手动插入索引值(实际数据集将比这大得多)。

由于这是针对大学课程的,我希望任何解决方案都尽可能简单:对于 R 语言经验很少的学生来说,for 循环和应用函数可能很难掌握。

4

2 回答 2

1

试试这个:

rMeans <- rowMeans(m, na.rm = T)
names(rMeans) <- NULL
which(rMeans == min(rMeans, na.rm = T))
# [1] 4

或者作为一个函数:

minMeanDist <- function(x) {
  m <- as.matrix(x)
  m[upper.tri(m)] <- NA
  m[m == 0] <- NA
  rMeans <- rowMeans(m, na.rm = T)
  names(rMeans) <- NULL
  mmd <- min(rMeans, na.rm = T)
  ind <- which(rMeans == mmd)
  list(index = ind, min_mean_dist = mmd)
}
minMeanDist(dist_m)
# $index
# [1] 4
# 
# $min_mean_dist
# [1] 6.900984
于 2018-01-09T13:32:38.713 回答
1

如果你想使用tidyverse这是一种方法:

as.matrix(dist_m) %>%
    as.tibble() %>%
    rownames_to_column(var = "start_node") %>%
    gather(end_node, dist, -start_node) %>% # go long
    filter(dist != 0) %>% # drop identity diagonal
    group_by(start_node) %>% # now summarise
    summarise(mean_dist = mean(dist)) %>%
    filter(mean_dist == min(mean_dist)) # chose minimum mean_dist

# A tibble: 1 x 2
  start_node mean_dist
       <chr>     <dbl>
1          4  6.900984

它有点长,但管道可以很容易地看到每一行发生的事情,并且你会得到一个很好的输出。

于 2018-01-09T14:56:00.370 回答