2017-10-04 150 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

如果我們將所有字符列factors設置爲'A','B','C','D',那麼我們可以使用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。但實際上,我仍然遇到問題,因爲我將變量存儲在數據框中。 df < - tribble(〜var1,〜var2,〜score,data3 $ var1,data3 $ var2,data3 $ score) df%>%mutate_if(is.character,factor,levels = c('data3 $ var1' ,'data3 $ var2'))%>%xtabs(score〜var1 + var2,。,drop.unused.levels = F)%>%'+'(。,t(。))' – Brenna

+0

您使用的方式'tribble'將導致列表欄。你可以使用'data3%>%mutate_if(是。字符,因子,水平= c('A','B','C','D'))%>%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 

有關詳細信息,請參閱矩陣和數組的幫助文件?"["部分。那裏的第四段討論了這種索引形式。

請注意,我假設前兩個變量是字符向量而不是因素。這使得它更容易一些,因爲我不必使用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))