3

私はRに比較的慣れていません。この質問が基本的すぎる場合はすみません。R を使用して完全なダイアレルを作成するための優れた高速な方法があるかどうか疑問に思っています。

次のようなマトリックスがあります。

          M1 M2 M3
   Line1  A  B  A
   Line2  A  A  B
   Line3  B  A  A

このマトリックスから、次のデータ フレームを作成したいと思います。

 X       Y       M1   M2  M3
 Line1   Line1   AA   BB  AA
 Line1   Line2   AA   BA  AB
 Line1   Line3   AB   BA  AA
 Line2   Line1   AA   AB  BA
 Line2   Line2   AA   AA  BB
 Line2   Line3   AB   AA  BA
 Line3  Line1    BA   AB  AA
 Line3  Line2    BA   AA  AB
 Line3  Line3    BB   AA  AA

これは、ネストされたループをいくつか作成し、ペーストを使用して A と B の文字コードを組み合わせることで可能になると思います。しかし、おそらくもっと優れた「R ライクな」オプション ( cbind()? を使用) があります。

4

2 に答える 2

2

1 つのアプローチは、目的の出力の各行を構成するデータ行のインデックスを考えることです。データの使用:

mat <- matrix(c("A","B","A",
                "A","A","B",
                "B","A","A"), ncol = 3, byrow = TRUE)

を使用してこれらのインデックスを作成しますexpand.grid()mat出力の最初の行は、 の行 1 と の行1 の連結などによって形成されますmat。これらのインデックスは次のように生成されます

> ind <- expand.grid(r1 = 1:3, r2 = 1:3)
> ind
  r1 r2
1  1  1
2  2  1
3  3  1
4  1  2
5  2  2
6  3  2
7  1  3
8  2  3
9  3  3

出力が示すものを取得するには、その逆ではなく列r2を取得する必要があることに注意してください。r1

matここで、 の 2 番目の列indと の 1番目の列にインデックスを付けて、それをベクトルである出力indに提供するpaste0()だけなので、それを行列に再形成する必要があります。

> matrix(paste0(mat[ind[,2], ], mat[ind[,1], ]), ncol = 3)
      [,1] [,2] [,3]
 [1,] "AA" "BB" "AA"
 [2,] "AA" "BA" "AB"
 [3,] "AB" "BA" "AA"
 [4,] "AA" "AB" "BA"
 [5,] "AA" "AA" "BB"
 [6,] "AB" "AA" "BA"
 [7,] "BA" "AB" "AA"
 [8,] "BA" "AA" "AB"
 [9,] "BB" "AA" "AA"

paste0()ステップは、貼り付けられた文字列のベクトルを返します。

> paste0(mat[ind[,2], ], mat[ind[,1], ])
 [1] "AA" "AA" "AB" "AA" "AA" "AB" "BA" "BA" "BB" "BB" "BA" "BA" "AB" "AA" "AA"
[16] "AB" "AA" "AA" "AA" "AB" "AA" "BA" "BB" "BA" "AA" "AB" "AA"

上記の行列の再構築が機能する理由の秘訣はpaste0()、インデックスindがどのように形成されたかにより、 からの出力のエントリが列優先順になっていることに注意することです。基本的に、 に渡される 2 つの引数は次のpaste0()とおりです。

> mat[ind[,2], ]
      [,1] [,2] [,3]
 [1,] "A"  "B"  "A" 
 [2,] "A"  "B"  "A" 
 [3,] "A"  "B"  "A" 
 [4,] "A"  "A"  "B" 
 [5,] "A"  "A"  "B" 
 [6,] "A"  "A"  "B" 
 [7,] "B"  "A"  "A" 
 [8,] "B"  "A"  "A" 
 [9,] "B"  "A"  "A" 
> mat[ind[,1], ]
      [,1] [,2] [,3]
 [1,] "A"  "B"  "A" 
 [2,] "A"  "A"  "B" 
 [3,] "B"  "A"  "A" 
 [4,] "A"  "B"  "A" 
 [5,] "A"  "A"  "B" 
 [6,] "B"  "A"  "A" 
 [7,] "A"  "B"  "A" 
 [8,] "A"  "A"  "B" 
 [9,] "B"  "A"  "A"

R はそれぞれをベクトルとして扱うため、出力はベクトルになりますが、R は行列を列ごとに格納するため、出力行列も列ごとに貼り付けられた文字列で埋めます。

于 2012-09-18T10:46:10.663 に答える
1

出力を取得するためにいくつかのループは必要ないかもしれませんが、ここに提案があります:

まず、サンプル マトリックスを生成しましょう。

M <- matrix(c("A","B","A","A","A","B","B","A","A"), ncol = 3, byrow = TRUE)
rownames(M) <- c("Line1","Line2","Line3")
colnames(M) <- c("M1","M2","M3")

ベクター内のアイテム間のすべての可能なペアを簡単に生成するには、次を使用しますexpand.grid()

d <- expand.grid(rownames(M), rownames(M))

目的の出力で列 X と Y を生成します。

   Var1  Var2
1 Line1 Line1
2 Line2 Line1
3 Line3 Line1
4 Line1 Line2
5 Line2 Line2
6 Line3 Line2
7 Line1 Line3
8 Line2 Line3
9 Line3 Line3

次に、apply()対応する M1、M2、M3 値を貼り付ける各行への関数を作成できます。

apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} )

正しい組み合わせが生成されますが、正しい形式ではありません (まだ):

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] "AA" "AA" "BA" "AA" "AA" "BA" "AB" "AB" "BB"
[2,] "BB" "AB" "AB" "BA" "AA" "AA" "BA" "AA" "AA"
[3,] "AA" "BA" "AA" "AB" "BB" "AB" "AA" "BA" "AA"

行列を正しい方向に反転するには、単純に転置する必要があります。

そこから、一度にすべてをデータ フレームにラップできます。

df <- data.frame( d, t(apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} ))
colnames(df) <- c("X","Y","M1","M2", "M3")

そしてここにあります。

より効率的にするために、最終的に任意の M 行列を送信する小さな関数を作成できます。

get.it <- function(M){ 
    d <- expand.grid(rownames(M), rownames(M))
    e <- t(apply(d, 1, function(x) { paste(M[x[1],], paste(M[x[2],]), sep="")} ))
    output<- data.frame( d, e)
    colnames(output) <- c("X","Y","M1","M2","M3")
return(output)
}

そしてget.it(M)うまくいくはずです!

于 2012-09-18T11:07:27.173 に答える