如何使用核心R操纵/访问"dist"类实例的元素?

Pau*_*die 20 indexing r class distance matrix

R中的基本/公共类被称为"dist",并且是对称距离矩阵的相对有效的表示."matrix"但是,与对象不同,似乎不支持"dist"使用"["运算符通过索引对操作实例.

例如,以下代码不返回任何内容NULL,或错误:

# First, create an example dist object from a matrix
mat1  <- matrix(1:100, 10, 10)
rownames(mat1) <- 1:10
colnames(mat1) <- 1:10
dist1 <- as.dist(mat1)
# Now try to access index features, or index values
names(dist1)
rownames(dist1)
row.names(dist1)
colnames(dist1)
col.names(dist1)
dist1[1, 2]
Run Code Online (Sandbox Code Playgroud)

同时,在某种意义上,以下命令可以正常工作,但不要使访问/操作特定索引对值更容易:

dist1[1] # R thinks of it as a vector, not a matrix?
attributes(dist1)
attributes(dist1)$Diag <- FALSE
mat2 <- as(dist1, "matrix")
mat2[1, 2] <- 0
Run Code Online (Sandbox Code Playgroud)

一个解决方法 - 我想避免 - 首先将"dist"对象转换为a "matrix",操纵该矩阵,然后将其转换回"dist".这也是说,这不是一个关于如何转换的问题一个"dist"实例为"matrix",或在共同的矩阵索引工具已经定义了一些其他类; 因为在不同的SO问题中已经以多种方式回答了这个问题

stats包中是否有工具(或者可能是其他一些核心R包)专用索引/访问实例的元素"dist"

小智 8

遗憾的是,没有标准的方法可以做到这一点.这是两个函数,它们将1D索引转换为2D矩阵坐标.它们并不漂亮,但它们可以工作,至少你可以使用代码在你需要的时候制作更好的东西.我发布它只是因为方程不明显.

distdex<-function(i,j,n) #given row, column, and n, return index
    n*(i-1) - i*(i-1)/2 + j-i

rowcol<-function(ix,n) { #given index, return row and column
    nr=ceiling(n-(1+sqrt(1+4*(n^2-n-2*ix)))/2)
    nc=n-(2*n-nr+1)*nr/2+ix+nr
    cbind(nr,nc)
}
Run Code Online (Sandbox Code Playgroud)

一个小测试工具,以显示它的工作原理:

dist(rnorm(20))->testd
as.matrix(testd)[7,13]   #row<col
distdex(7,13,20) # =105
testd[105]   #same as above

testd[c(42,119)]
rowcol(c(42,119),20)  # = (3,8) and (8,15)
as.matrix(testd)[3,8]
as.matrix(testd)[8,15]
Run Code Online (Sandbox Code Playgroud)


flo*_*del 7

我对你的问题没有直接的答案,但是如果你使用欧几里德距离,请查看包中的rdist函数fields.它的实现(在Fortran中)比它快dist,并且输出是类的matrix.至少,它表明一些开发人员选择离开这个dist类,可能是因为你提到的确切原因.如果您担心使用full matrix来存储对称矩阵是对内存的低效使用,您可以将其转换为三角矩阵.

library("fields")
points <- matrix(runif(1000*100), nrow=1000, ncol=100)

system.time(dist1 <- dist(points))
#    user  system elapsed 
#   7.277   0.000   7.338 

system.time(dist2 <- rdist(points))
#   user  system elapsed 
#  2.756   0.060   2.851 

class(dist2)
# [1] "matrix"
dim(dist2)
# [1] 1000 1000
dist2[1:3, 1:3]
#              [,1]         [,2]         [,3]
# [1,] 0.0000000001 3.9529674733 3.8051198575
# [2,] 3.9529674733 0.0000000001 3.6552146293
# [3,] 3.8051198575 3.6552146293 0.0000000001
Run Code Online (Sandbox Code Playgroud)


Hon*_*Ooi 5

as.matrix(d)将把dist对象d变成矩阵,而as.dist(m)将矩阵变mdist对象。请注意,后者实际上并不会检查它m是否是有效的距离矩阵。它只是提取下三角部分。