2017-10-04 176 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))