将三列数据帧重新整形为矩阵("长"到"宽"格式)

Mal*_*dog 121 r matrix plyr reshape dataframe

我有一个data.frame看起来像这样的.

x a 1 
x b 2 
x c 3 
y a 3 
y b 3 
y c 2 
Run Code Online (Sandbox Code Playgroud)

我想以矩阵形式这样做,所以我可以将它送到热图以制作情节.结果应该类似于:

    a    b    c
x   1    2    3
y   3    3    2
Run Code Online (Sandbox Code Playgroud)

我已尝试cast从reshape包中尝试编写手动函数来执行此操作,但我似乎无法正确执行此操作.

Aar*_*ica 174

有很多方法可以做到这一点.这个答案从我最喜欢的方式开始,但也收集各种方式从答案到分散在这个网站周围的类似问题.

tmp <- data.frame(x=gl(2,3, labels=letters[24:25]),
                  y=gl(3,1,6, labels=letters[1:3]), 
                  z=c(1,2,3,3,3,2))
Run Code Online (Sandbox Code Playgroud)

使用tidyverse:

这是一个很酷的新方法,pivot_wider来自tidyr.它返回一个数据框,这可能是这个答案的大多数读者想要的.但是,对于热图,您需要将其转换为真正的矩阵.

library(tidyr)
pivot_wider(tmp, names_from = y, values_from = z)
## # A tibble: 2 x 4
## x         a     b     c
## <fct> <dbl> <dbl> <dbl>
## 1 x       1     2     3
## 2 y       3     3     2
Run Code Online (Sandbox Code Playgroud)

使用reshape2:

这个tidyverse的第一步是reshape2包.我仍然认为,对于许多重塑任务,这些tidyr 1.0.0spread功能比整齐的方式更清晰,更简单.

要获得矩阵使用tidyr:

library(tidyr)
spread(tmp, y, z)
##   x a b c
## 1 x 1 2 3
## 2 y 3 3 2
Run Code Online (Sandbox Code Playgroud)

或者要获取数据框,请使用acast,如下所示:重新整理一列中值的数据.

library(reshape2)
acast(tmp, x~y, value.var="z")
##   a b c
## x 1 2 3
## y 3 3 2
Run Code Online (Sandbox Code Playgroud)

使用plyr:

在reshape2和tidyverse之间dcast,使用该plyr功能,如下所示:https://stackoverflow.com/a/7020101/210673

dcast(tmp, x~y, value.var="z")
##   x a b c
## 1 x 1 2 3
## 2 y 3 3 2
Run Code Online (Sandbox Code Playgroud)

使用矩阵索引:

这是一个古老的学校,但它是矩阵索引的一个很好的演示,它在某些情况下非常有用.

library(plyr)
daply(tmp, .(x, y), function(x) x$z)
##    y
## x   a b c
##   x 1 2 3
##   y 3 3 2
Run Code Online (Sandbox Code Playgroud)

使用daply:

with(tmp, {
  out <- matrix(nrow=nlevels(x), ncol=nlevels(y),
                dimnames=list(levels(x), levels(y)))
  out[cbind(x, y)] <- z
  out
})
Run Code Online (Sandbox Code Playgroud)

使用稀疏矩阵:

还有xtabs的内sparseMatrix包,在这里看到:的R -转换大表到矩阵的列名

xtabs(z~x+y, data=tmp)
Run Code Online (Sandbox Code Playgroud)

使用Matrix:

您还可以使用基本R函数reshape,如下所示:按列名称将表转换为矩阵,但之后必须稍微操作以删除额外的列并使名称正确(未显示).

with(tmp, sparseMatrix(i = as.numeric(x), j=as.numeric(y), x=z,
                       dimnames=list(levels(x), levels(y))))
## 2 x 3 sparse Matrix of class "dgCMatrix"
##   a b c
## x 1 2 3
## y 3 3 2
Run Code Online (Sandbox Code Playgroud)

  • `acast(tmp,x~y,value.var ="z")`将给出一个矩阵输出,其中`x`为row.names (2认同)
  • 在大多数小型数据集中,首要考虑的因素应该是以未来分析师(包括未来的您)清楚且最不容易出现人为编码错误的方式进行编码。尽管这取决于您的优势和需求,但通常这被认为是新的 tidyverse 软件包集的优势之一。另一个考虑因素(虽然不是真正的优点/缺点)是你想要一个矩阵还是一个数据框作为结果;这个问题特别要求一个矩阵,您可以在答案中看到有些技术直接给出矩阵,而有些技术则给出数据框。 (2认同)