2016-12-16 6 views
2

Rの新機能、および私の頭の中で!列間のペアごとの計算を使用して行列を作成するR

私は、次の手順を結合しますコードを記述しようとしています:

a)は2列

b)の最小値が見つかった合計と、行ごとに、最小値を探す

C )多くの列でこれを行い、結果のペアワイズ行列を構築します。

手順a & bは、一度に2つの列に対して十分に簡単です。このように:

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コードで起こっているになって何見当がつかないあなたはもう、最小値を加算しているように、それは見ていません。

私がループするつもりだったら、combnの代わりにexpand.gridを使用します。対角線を取得して、マトリックスの両面をどのように埋めるかを決める必要はありませんが、すべての計算を2回行います。 (コンピュータは、それを2回行うことができますが、それは1度だけ行う方法を考え出すよりも簡単です)また、ベクトルとして作成してから、後で行列に変換します。

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への感謝を学び、彼のコメントは、Rは、列で値を満たしているので、res[lower.tri(res)] <- res[upper.tri(res)]が動作しないということであることに注意すること)

や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およびupper。triはそのように対称ではありません。 – Aaron

+0

@Aaron申し訳ありませんが、私はそれをあなたが説明することができませんでしたか? – User2321

+1

4番目の列を追加して試してみると、Rが常に列で塗りつぶされるため、結果の行列が対称ではないことがわかります。しかし、それは良い答えです。私はちょうどあなたの内側ループを1に始めることを提案するでしょう。 – Aaron

関連する問題