从数据框创建方阵

时间:2017-10-04 10:06:26

标签: r matrix dataframe

我无法从我的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中可用的不同软件包中的许多功能,但仍无法找到解决方案。

2 个答案:

答案 0 :(得分:6)

这是一个在字符向量上使用矩阵索引的基本R方法。

## set up storage 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))

答案 1 :(得分:4)

如果我们将所有字符列factor设为“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