如何从长到宽的格式重塑数据?

我在重新排列下面的数据框时遇到了问题:

set.seed(45) dat1 <- data.frame( name = rep(c("firstName", "secondName"), each=4), numbers = rep(1:4, 2), value = rnorm(8) ) dat1 name numbers value 1 firstName 1 0.3407997 2 firstName 2 -0.7033403 3 firstName 3 -0.3795377 4 firstName 4 -0.7460474 5 secondName 1 -0.8981073 6 secondName 2 -0.3347941 7 secondName 3 -0.5013782 8 secondName 4 -0.1745357 

我想重塑它,以便每个唯一的“名称”variables是rowname,其中“values”作为该行的观察值,“numbers”作为colnames。 有点像这样:

  name 1 2 3 4 1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474 5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357 

我已经看过melt和其他一些东西,但是似乎没有人能够完成这项工作。

使用reshapefunction:

 reshape(dat1, idvar = "name", timevar = "numbers", direction = "wide") 

新的(2014年) tidyr包也做到这一点, tidyr gather() / spread()melt / cast的条款。

 library(tidyr) spread(dat1, key = numbers, value = value) 

从github ,

tidyr是为了配合整洁的数据框架而reshape2devise的一个reshape2 ,并且与magrittrdplyr携手magrittr ,为数据分析打造一个坚实的pipe道。

就像重塑2的重塑一样,重塑不如重塑reshape2 。 它是专门为整理数据而devise的,而不是整形重塑的reshape2 ,或者是整形。 特别是,内置的方法只适用于数据框架, tidyr提供边距或聚合。

你可以用reshape()函数或者在重塑包中使用melt() / cast()函数来做到这一点。 对于第二种select,示例代码是

 library(reshape) cast(dat1, name ~ numbers) 

或者使用reshape2

 library(reshape2) dcast(dat1, name ~ numbers) 

使用您的示例数据框,我们可以:

 xtabs(value ~ name + numbers, data = dat1) 

另一个select,如果性能是一个问题是使用data.tablereshape2的融合和dcastfunction的扩展

( 参考:使用data.tables进行高效的整形 )

 library(data.table) setDT(dat1) dcast(dat1, name ~ numbers, value.var = "value") # name 1 2 3 4 # 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 # 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 

而且,从data.table v1.9.6开始,我们可以在多列上投射

 ## add an extra column dat1[, value2 := value * 2] ## cast multiple value columns dcast(dat1, name ~ numbers, value.var = c("value", "value2")) # name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4 # 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155 # 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627 

其他两个选项:

基础包:

 df <- unstack(dat1, form = value ~ numbers) rownames(df) <- unique(dat1$name) df 

sqldf包:

 library(sqldf) sqldf('SELECT name, MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1, MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2, MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3, MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4 FROM dat1 GROUP BY name') 

使用base R aggregate函数:

 aggregate(value ~ name, dat1, paste) # name value.1 value.2 value.3 value.4 #1 firstName 0.4145 -0.4747 0.0659 -0.5024 #2 secondName -0.8259 0.1669 -0.8962 0.1681