2016-01-19 104 views
0

假設我有一個看起來像這樣的矩陣,並將其轉換爲dist類對象(無對角線),然後將其轉換爲向量爲了以後的目的。相當於二維矩陣索引的dist矩陣(一維向量)中的索引,在R

m = matrix(c(0,1,2,3, 1,0,3,4, 2,3,0,5, 3,4,5,0), nrow=4) 
#m: 
    [,1] [,2] [,3] [,4] 
[1,] 0 1 2 3 
[2,] 1 0 3 4 
[3,] 2 3 0 5 
[4,] 3 4 5 0 
md = as.dist(m, diag=F) 
# md: 
    1 2 3 
2 1  
3 2 3 
4 3 4 5 

mdv = as.vector(md) 
# 1 2 3 3 4 5 

我可以訪問原始矩陣照常與[],我也很容易訪問的一維指數(,例如第3行,列2)使用m[ 3+((2-1)*4) ]。 dist對象(和向量)是一維的,但是隻包含原始矩陣的下三角形(並且由於對角線已被刪除,所以也沒有來自每個原始列/行的一個元素)。

我以後如何訪問矢量mdv中的等效元素?所以例如我如何訪問對象mdv中的m[3,2](值3)的等效項? (不是按值,因爲可能有重複的值,而是通過索引)相關Q & A解決dist對象上as.matrix的類似問題,但是這對我沒有幫助(因爲我需要處理矢量)。

+1

您可以轉換'dist'到'matrix'用'as.matrix' – akrun

回答

0

具有lower.tri(, diag = FALSE)距離向量(「MDV」),你可以(1)的距離矩陣(「M」)的find the respective dimensions和(2)通過減去等效缺失「upper.tri」相應地轉換i + (j - 1)*nrow指數。

ff = function(x, i, j) 
{ 
    #assumes that 'x' is a valid distances vector that results in correct 'n' 
    n = (1 + sqrt(1 + 8 * length(x)))/2 

    #make sure i >= j 
    ii = pmax(i, j); jj = pmin(i, j) 

    #insert 0s to handle 'i == j' 
    x = c(unlist(lapply(split(x, rep(seq_len(n - 1), (n - 1):1)), 
         function(X) c(0, X)), FALSE, FALSE), 0) 

    #subtract the missing `upper.tri` elements 
    x[(ii + (jj - 1L) * n) - cumsum(0:(n - 1))[jj]] 
} 

例如爲:

n = 3 
m = matrix(0, n, n); m[lower.tri(m)] = runif(choose(n, 2)); m = m + t(m); x = c(as.dist(m)) 
m 
#   [,1]  [,2]  [,3] 
#[1,] 0.0000000 0.3796833 0.5199015 
#[2,] 0.3796833 0.0000000 0.4770344 
#[3,] 0.5199015 0.4770344 0.0000000 
m[cbind(c(2, 2, 3, 1), c(3, 2, 1, 2))] 
#[1] 0.4770344 0.0000000 0.5199015 0.3796833 
ff(x, c(2, 2, 3, 1), c(3, 2, 1, 2)) 
#[1] 0.4770344 0.0000000 0.5199015 0.3796833 

n = 23 
m = matrix(0, n, n); m[lower.tri(m)] = runif(choose(n, 2)); m = m + t(m); x = c(as.dist(m)) 
i = sample(seq_len(n), 25, TRUE); j = sample(seq_len(n), 25, TRUE) 
all.equal(m[cbind(i, j)], ff(x, i, j)) 
#[1] TRUE 

等等

0

這個怎麼樣功能:

fun <- function(r, c){ 
    stopifnot(r != c) 
    if(r > c) (r-2)*(r-1)/2 + c 
    else (c-2)*(c-1)/2 + r 
} 

mdv[fun(1, 2)] # 1 
mdv[fun(2, 3)] # 3 
mdv[fun(3, 4)] # 5 
mdv[fun(2, 1)] # 1 
mdv[fun(3, 2)] # 3 
mdv[fun(1, 1)] # stop 

r == c應申請fun前處理。爲了方便,您可以編寫另一個函數來處理這種情況。