从 R 中的距离矩阵中提取对角线
Extract diagonals from a distance matrix in R
我想知道如何从距离矩阵中提取第一条对角线的值。
例如:
> mymatrix
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 6 4
[4,] 8 6
> dist(mymatrix)
1 2 3
2 2.828427
3 5.385165 3.000000
4 8.062258 5.385165 2.828427
我想在向量中获取以下值:2.828427, 3.000000, 2.828427
谢谢!
一种解决方法是将 dist
对象转换为 matrix
,然后提取行索引比列索引大一个的元素:
mat = as.matrix(dist(mymatrix))
mat[row(mat) == col(mat) + 1]
# [1] 2.828427 3.000000 2.828427
提取"dist"矩阵的第d
th次对角线的看似复杂但极其有效的解决方案。
subdiag <- function (dist_obj, d) {
if (!inherits(dist_obj, "dist")) stop("please provide a 'dist' object!")
n <- attr(dist_obj, "Size")
if (d < 1 || d > (n - 1)) stop(sprintf("'d' needs be between 1 and %d", n - 1L))
j_1 <- c(0, seq.int(from = n - 1, by = -1, length = n - d - 1))
subdiag_ind <- d + cumsum(j_1)
dist_obj[subdiag_ind]
}
有关 "dist" 对象的打包存储的详细信息,请参见 。在这个函数中,j_1
是第(j - 1)
列中“X
”的个数。 cumsum
给出主对角线的一维索引(其值全为零)。 d
的进一步偏移给出 d
th 次对角线的一维索引。
set.seed(0)
x <- dist(matrix(runif(10), 5))
# 1 2 3 4
#2 0.9401067
#3 0.9095143 0.1162289
#4 0.5618382 0.3884722 0.3476762
#5 0.4275871 0.6968296 0.6220650 0.3368478
subdiag(x, 1)
#[1] 0.9401067 0.1162289 0.3476762 0.3368478
lapply(1:4, subdiag, dist_obj = x)
#[[1]]
#[1] 0.9401067 0.1162289 0.3476762 0.3368478
#
#[[2]]
#[1] 0.9095143 0.3884722 0.6220650
#
#[[3]]
#[1] 0.5618382 0.6968296
#
#[[4]]
#[1] 0.4275871
从大到大 "dist" 矩阵的良好性能。
## mimic a "dist" object without actually calling function `dist`
n <- 2000
x <- structure(numeric(n * (n - 1) / 2), class = "dist", Size = n)
library(bench)
bench::mark("Psidom" = {mat = as.matrix(x); mat[row(mat) == col(mat) + 1]},
"zheyuan" = subdiag(x, 1))
## A tibble: 2 x 14
# expression min mean median max `itr/sec` mem_alloc n_gc n_itr
# <chr> <bch:tm> <bch:tm> <bch:t> <bch:tm> <dbl> <bch:byt> <dbl> <int>
#1 Psidom 553ms 553ms 553ms 552.74ms 1.81 251.8MB 5 1
#2 zheyuan 106µs 111µs 108µs 3.85ms 9045. 62.7KB 2 4519
## ... with 5 more variables: total_time <bch:tm>, result <list>, memory <list>,
## time <list>, gc <list>
subdiag
速度提高了 5120 倍 (553ms / 108µs),内存效率提高了 4112 倍 (251.8MB / 62.7KB)。
我想知道如何从距离矩阵中提取第一条对角线的值。
例如:
> mymatrix
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 6 4
[4,] 8 6
> dist(mymatrix)
1 2 3
2 2.828427
3 5.385165 3.000000
4 8.062258 5.385165 2.828427
我想在向量中获取以下值:2.828427, 3.000000, 2.828427
谢谢!
一种解决方法是将 dist
对象转换为 matrix
,然后提取行索引比列索引大一个的元素:
mat = as.matrix(dist(mymatrix))
mat[row(mat) == col(mat) + 1]
# [1] 2.828427 3.000000 2.828427
提取"dist"矩阵的第d
th次对角线的看似复杂但极其有效的解决方案。
subdiag <- function (dist_obj, d) {
if (!inherits(dist_obj, "dist")) stop("please provide a 'dist' object!")
n <- attr(dist_obj, "Size")
if (d < 1 || d > (n - 1)) stop(sprintf("'d' needs be between 1 and %d", n - 1L))
j_1 <- c(0, seq.int(from = n - 1, by = -1, length = n - d - 1))
subdiag_ind <- d + cumsum(j_1)
dist_obj[subdiag_ind]
}
有关 "dist" 对象的打包存储的详细信息,请参见 j_1
是第(j - 1)
列中“X
”的个数。 cumsum
给出主对角线的一维索引(其值全为零)。 d
的进一步偏移给出 d
th 次对角线的一维索引。
set.seed(0)
x <- dist(matrix(runif(10), 5))
# 1 2 3 4
#2 0.9401067
#3 0.9095143 0.1162289
#4 0.5618382 0.3884722 0.3476762
#5 0.4275871 0.6968296 0.6220650 0.3368478
subdiag(x, 1)
#[1] 0.9401067 0.1162289 0.3476762 0.3368478
lapply(1:4, subdiag, dist_obj = x)
#[[1]]
#[1] 0.9401067 0.1162289 0.3476762 0.3368478
#
#[[2]]
#[1] 0.9095143 0.3884722 0.6220650
#
#[[3]]
#[1] 0.5618382 0.6968296
#
#[[4]]
#[1] 0.4275871
从大到大 "dist" 矩阵的良好性能。
## mimic a "dist" object without actually calling function `dist`
n <- 2000
x <- structure(numeric(n * (n - 1) / 2), class = "dist", Size = n)
library(bench)
bench::mark("Psidom" = {mat = as.matrix(x); mat[row(mat) == col(mat) + 1]},
"zheyuan" = subdiag(x, 1))
## A tibble: 2 x 14
# expression min mean median max `itr/sec` mem_alloc n_gc n_itr
# <chr> <bch:tm> <bch:tm> <bch:t> <bch:tm> <dbl> <bch:byt> <dbl> <int>
#1 Psidom 553ms 553ms 553ms 552.74ms 1.81 251.8MB 5 1
#2 zheyuan 106µs 111µs 108µs 3.85ms 9045. 62.7KB 2 4519
## ... with 5 more variables: total_time <bch:tm>, result <list>, memory <list>,
## time <list>, gc <list>
subdiag
速度提高了 5120 倍 (553ms / 108µs),内存效率提高了 4112 倍 (251.8MB / 62.7KB)。