我无法从我的data.frame中制作一个方阵.现在我的数据看起来像这样:
var1 var2 value
A B 4
C D 5
D A 2
B D 1
Run Code Online (Sandbox Code Playgroud)
我正在尝试将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
Run Code Online (Sandbox Code Playgroud)
我尝试了R中可用的不同包中的许多功能,但仍无法找到解决方案.
这是一个在字符向量上使用矩阵索引的基本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"]]
Run Code Online (Sandbox Code Playgroud)
这回来了
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
Run Code Online (Sandbox Code Playgroud)
有关这种强大的索引形式如何工作的详细信息,请参阅帮助文件的矩阵和数组部分?"[".特别是,本节的第四段讨论了这种索引形式.
请注意,我假设前两个变量是字符向量而不是因子.这使得它更容易一些,因为我不必使用它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))
Run Code Online (Sandbox Code Playgroud)
如果我们使所有字符列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
Run Code Online (Sandbox Code Playgroud)
为了使其对称,我只是将其转置添加到自身。不过,这感觉有点像黑客。
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2712 次 |
| 最近记录: |