2017-10-04 7 views
5

自分のdata.frameから正方行列を作るのに問題があります。データフレームから正方行列を作成する

var1 var2 value 
    A B  4 
    C D  5 
    D A  2 
    B D  1 

私はこのようになります行列にdata.frameを変換しようとしている:私は利用可能な異なるパッケージから多くの機能を試してみました

A B C D 
    A 0 4 0 2 
    B 4 0 0 1 
    C 0 0 0 5 
    D 2 1 5 0 

今、私のデータは次のようになりますRではまだ解を見つけることができません。

+0

あなたは試してみましたが、それらの多くの機能を投稿してください、それが – PoGibas

+1

'XTABS(値〜VAR1 + VAR2、DF)'を動作しませんでしたなぜですか? – Sotos

+1

@Sotosこれはカラム 'C'を見逃すでしょう – PoGibas

答えて

3

レベル 'A'、 'B'、 'C​​'、 'D'のすべての文字列factorを作成すると、列を削除せずにxtabsを使用できます。

残念ながら、結果の行列は対称ではありません。

library('tidyverse') 

df <- tribble(
    ~var1, ~var2, ~value, 
    'A', 'B',  4, 
    'C', 'D',  5, 
    'D', 'A',  2, 
    'B', 'D',  1 
) 

df %>% 
    mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>% 
    xtabs(value ~ var1 + var2, ., drop.unused.levels = F) 
#  var2 
# var1 A B C D 
# A 0 4 0 0 
# B 0 0 0 1 
# C 0 0 0 5 
# D 2 0 0 0 

対称にするために、私は自分自身にトランスポーズを追加しました。しかし、これはちょっとしたハックのような感じです。

df %>% 
    mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>% 
    xtabs(value ~ var1 + var2, ., drop.unused.levels = F) %>% 
    '+'(., t(.)) 
#  var2 
# var1 A B C D 
# A 0 4 0 2 
# B 4 0 0 1 
# C 0 0 0 5 
# D 2 1 5 0 
+0

"これは次のような感じです。(これは、しかし、ちょっとしたハックだよ " - Rで多くの良い解決法について言えることでしょう+1 +1 –

+0

詳細な返信ありがとうございます@Paul。しかし実際には、データフレームに変数を格納するので、まだ問題はあります。 (data3 $ var1、data3 $ var1、data3 $ var1、data3 $ var1、data3 $ score) df%>%mutate_if(文字列、 、 'data3 $ var2'))%>%xtabs(スコア〜var1 + var2、。、drop.unused.levels = F)%>% '+'(。、t(。)) ' – Brenna

+0

'tribble'はリスト列になります。 'data3%>%mutate_ifを使うことができます(is。%xtabs(score〜var1 + var2、。、drop.unused.levels = F)%>% '、%、'% '、% + '(。、t(。)) ' – Paul

3

ここでは、文字ベクタに対して行列インデックスを使用するベースRの方法があります。

## set up matrix 
# get names for row and columns 
nameVals <- sort(unique(unlist(dat[1:2]))) 
# construct 0 matrix of correct dimensions with row and column names 
myMat <- matrix(0, length(nameVals), length(nameVals), dimnames = list(nameVals, nameVals)) 

# fill in the matrix with matrix indexing on row and column names 
myMat[as.matrix(dat[c("var1", "var2")])] <- dat[["value"]] 

これは、このインデックスがどのように動作するかの詳細については

myMat 
    A B C D 
A 0 4 0 0 
B 0 0 0 1 
C 0 0 0 5 
D 2 0 0 0 

を返し、ヘルプファイル?"["行列と配列セクションを参照してください。そこの第4段落では、この形式の索引付けについて説明します。

最初の2つの変数は要素ではなく文字ベクトルであると仮定しています。これは、私がas.characterを強要するために使用する必要がないので、少し楽になります。

結果をdata.frameに変換するには、as.data.frameに簡単にラップします。

データ

dat <- 
structure(list(var1 = c("A", "C", "D", "B"), var2 = c("B", "D", 
"A", "D"), value = c(4L, 5L, 2L, 1L)), .Names = c("var1", "var2", 
"value"), class = "data.frame", row.names = c(NA, -4L)) 
関連する問題