我无法从我的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 :(得分: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