我想将矩阵重铸为一个数据框,其中一列用于行,一列用于列,一个用于存储在矩阵中的实际值。
让我们有一个像这样的例子矩阵:
mat <- matrix(paste0(rep(1:5,3), rep(1:3,each=5)), 5, 3)
mat
# [,1] [,2] [,3]
# [1,] "11" "12" "13"
# [2,] "21" "22" "23"
# [3,] "31" "32" "33"
# [4,] "41" "42" "43"
# [5,] "51" "52" "53"
使用as.vector()
和rep()
我可以构建想要的结果:
values <- as.vector(mat)
rows <- rep(seq_len(dim(mat)[1]), dim(mat)[2])
columns <- rep(seq_len(dim(mat)[2]), each=dim(mat)[1])
df <- data.frame(rows, columns, values)
df
# rows columns values
# 1 1 1 11
# 2 2 1 21
# 3 3 1 31
# 4 4 1 41
# 5 5 1 51
# 6 1 2 12
# 7 2 2 22
# 8 3 2 32
# 9 4 2 42
# 10 5 2 52
# 11 1 3 13
# 12 2 3 23
# 13 3 3 33
# 14 4 3 43
# 15 5 3 53
现在,在R或其中一个软件包中是否有现成可能更多高性能功能吗?
答案 0 :(得分:3)
您可以尝试which
并使用arr.ind
参数
values <- as.vector(mat)
data.frame(which(mat == values, arr.ind = TRUE), values)
# row col values
# 1 1 1 11
# 2 2 1 21
# 3 3 1 31
# 4 4 1 41
# 5 5 1 51
# 6 1 2 12
# 7 2 2 22
# 8 3 2 32
# 9 4 2 42
# 10 5 2 52
# 11 1 3 13
# 12 2 3 23
# 13 3 3 33
# 14 4 3 43
# 15 5 3 53
答案 1 :(得分:3)
使用reshape2
包:
melt(mat)
Var1 Var2 value
1 1 1 11
2 2 1 21
3 3 1 31
4 4 1 41
5 5 1 51
6 1 2 12
7 2 2 22
8 3 2 32
9 4 2 42
10 5 2 52
11 1 3 13
12 2 3 23
13 3 3 33
14 4 3 43
15 5 3 53
基础R的解决方案:
as.data.frame.table(mat)
但是,上面的代码没有产生所需的输出,因为矩阵没有行/列名,而as.data.frame.table()则放置字母。但是,如果矩阵具有行/列名称,则可以使用:
rownames(mat) = 1:5
colnames(mat) = 1:3
as.data.frame.table(mat)
话虽如此,根据我的经验,melt
使用大型矩阵的速度更快。
答案 2 :(得分:2)
另一种选择是:
data.frame(Var1=c(row(mat)), Var2=c(col(mat)), value=c(mat))
答案 3 :(得分:1)
expand.grid
可以有效地生成行和列组合,然后您可以cbind
数据:
cbind(expand.grid(rows=seq(nrow(mat)),columns=seq(ncol(mat))),values=c(mat))
rows columns values
1 1 1 11
2 2 1 21
3 3 1 31
4 4 1 41
5 5 1 51
6 1 2 12
7 2 2 22
8 3 2 32
9 4 2 42
10 5 2 52
11 1 3 13
12 2 3 23
13 3 3 33
14 4 3 43
15 5 3 53
答案 4 :(得分:-1)
R基础中的现成函数是as.data.frame.table
:
as.data.frame.table(mat)
## Var1 Var2 Freq
## 1 A A 11
## 2 B A 21
## 3 C A 31
## etc.
它使用mat
的行和列名称作为前两个输出列中的值,如果没有,则默认为大写字母,如上所示。
如果您不喜欢字母,请指定dimnames
,例如试试这个指定数字而不是字母,并指定rows
,columns
和value
作为列名:
dimnames(mat) <- list(rows = 1:nrow(mat), columns = 1:ncol(mat))
as.data.frame.table(mat, responseNAme = "value")
## rows columns value
## 1 1 1 11
## 2 2 1 21
## 3 3 1 31
## etc.
或使用数字但不更改列名的非破坏性版本:
as.data.frame.table(mat, base = list(paste(1:nrow(mat)), paste(1:ncol(mat))))
## Var1 Var2 Freq
## 1 1 1 11
## 2 2 1 21
## 3 3 1 31
## etc.