是否有现成的函数将矩阵转换为行,列和值的数据框?

时间:2014-09-23 09:08:38

标签: r matrix dataframe

我想将矩阵重铸为一个数据框,其中一列用于行,一列用于列,一个用于存储在矩阵中的实际值。

让我们有一个像这样的例子矩阵:

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或其中一个软件包中是否有现成可能更多高性能功能吗?

5 个答案:

答案 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,例如试试这个指定数字而不是字母,并指定rowscolumnsvalue作为列名:

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.