2016-12-16 114 views
2

新的R,並在我的頭!使用R中列間的成對計算創建矩陣R

我想編寫的代碼,將結合以下步驟:

a)求最小值,每行,兩列

B)之和最小值之間找到

Ç )在許多列中執行此操作並構造結果的成對矩陣

步驟a & b對於一次兩列很容易。像這樣:

column1 = c(0.08, 0.20, 0.09, 0.19, 0.25, 0.20, 0.00) 
column2 = c(0.07, 0.19, 0.09, 0.21, 0.25, 0.19, 0.00) 
ps = data.frame(column1, column2) 

sum(pmin(ps$column1,ps$column2)) 

但對於步驟c中,我有困難編寫將用於由7行32列的數據幀的每個成對列比較執行此操作代碼。這是我到目前爲止:

d <- replicate(32, rnorm(7)) 
c <- combn(seq_len(ncol(d)),2) 
mat1 <- matrix(0,ncol=32,nrow=32,dimnames=list(colnames(d),colnames(d))) 
v1 <- unlist(lapply(seq_len(ncol(c)),function(i) {d1<-d[,c[,i]]; length(which(d1[,1]!=0 & d1[,2]!=0)) })) 

mat1[lower.tri(mat1)]<-v1 

我很確定我的問題在於與「v1」相關的「功能」命令。但我很難過,可以真正使用一點幫助!

同樣,我的目標是在每個成對列比較之間有一個總和最小值的32x32矩陣。

這是否有意義?

非常感謝。

回答

2

outer功能會做到這一點,並跟蹤簿記的你,但你要傳遞一個量化的功能。

summin <- Vectorize(function(i, j) sum(pmin(ps[[i]], ps[[j]]))) 
outer(seq_len(ncol(ps)), seq_len(ncol(ps)), FUN=summin) 
##  [,1] [,2] 
## [1,] 1.01 0.98 
## [2,] 0.98 1.00 

我不知道是應該在你的v1代碼怎麼回事,它看起來並不像你再求和最小值。

如果我要循環自己,我會使用expand.grid而不是combn,因爲然後我得到對角線,並且不必知道如何填充矩陣的兩邊,但是犧牲了做兩次所有的計算。 (無論如何,計算機可以做得比我想象的要快兩倍。)我也將它作爲一個矢量,然後轉換爲矩陣。

cc <- expand.grid(seq_len(ncol(d)), seq_len(ncol(d))) 
out <- sapply(seq_len(nrow(cc)), function(k) { 
    i <- cc[k,1] 
    j <- cc[k,2] 
    sum(pmin(d[[i]],d[[j]])) 
}) 
out <- matrix(out, ncol=ncol(d)) 
+0

嗨亞倫,我用你的第一個建議,它效果很好!非常感謝你幫助我解決這個問題! – Monte

1

我想你可以嘗試以下方法(這是一個簡單的方法我不得不承認):

column1 = c(0.08, 0.20, 0.09, 0.19, 0.25, 0.20, 0.00) 
column2 = c(0.07, 0.19, 0.09, 0.21, 0.25, 0.19, 0.00) 
column3 = c(0.05, 0.49, 0.39, 0.1, 0.5, 0.11, 0.01) 
ps = data.frame(column1, column2, column3) 

res <-matrix(nrow = ncol(ps), ncol = ncol(ps)) 

for (i in (1:ncol(ps))) { 

    for (j in (i:ncol(ps))){ 

    res[i,j] <- sum(pmin(ps[,i],ps[,j])) 
    } 

} 

爲了利用的事實,即矩陣是對稱的,你可以這樣做:

res[lower.tri(res)] <- t(res)[lower.tri(res)] 

(有一點要注意,我還學會了感謝@Aaron和他的評論是,res[lower.tri(res)] <- res[upper.tri(res)]不起作用,因爲R被列填充值)

或AL ternatively(再次感謝阿倫),你可以做(​​和跳過最後一步)

for (i in (1:ncol(ps))) { 

     for (j in (i:ncol(ps))){ 

     res[i,j] <- res[j,i] <- sum(pmin(ps[,i],ps[,j])) 
     } 

    } 
+0

小心,lower.tri和上。三不是那樣對稱的。 – Aaron

+0

@Aaron抱歉,我沒有得到,你能解釋一下嗎? – User2321

+1

添加第四列,並嘗試它,你會看到所產生的基質是不是對稱的,爲R總是被列罷了。不過,這是一個很好的答案;我只是建議讓你的內循環從1開始。 – Aaron