一次重塑多个值

我有一个很长的数据集,我想扩大,我很好奇,如果有一种方法,在R一步使用reshape2或tidyr包完成这一切。

dataframedf如下所示:

 id type transactions amount 20 income 20 100 20 expense 25 95 30 income 50 300 30 expense 45 250 

我想要得到这个:

 id income_transactions expense_transactions income_amount expense_amount 20 20 25 100 95 30 50 45 300 250 

我知道我可以通过例如reshape2获得部分path:

 dcast(df, id ~ type, value.var="transactions") 

但是,是否有办法一次性重塑整个DF,同时解决“交易”和“金额”两个variables? 理想情况下,新的更适合的列名称?

在“reshape2”中,你可以使用recast (虽然根据我的经验,这不是一个广为人知的function)。

 library(reshape2) recast(mydf, id ~ variable + type, id.var = c("id", "type")) # id transactions_expense transactions_income amount_expense amount_income # 1 20 25 20 95 100 # 2 30 45 50 250 300 

你也可以使用base R的reshape

 reshape(mydf, direction = "wide", idvar = "id", timevar = "type") # id transactions.income amount.income transactions.expense amount.expense # 1 20 20 100 25 95 # 3 30 50 300 45 250 

或者,你可以像这样(这里用“data.table”)来meltdcast

 library(data.table) library(reshape2) dcast.data.table(melt(as.data.table(mydf), id.vars = c("id", "type")), id ~ variable + type, value.var = "value") # id transactions_expense transactions_income amount_expense amount_income # 1: 20 25 20 95 100 # 2: 30 45 50 250 300 

在“data.table”(1.9.8)的dcast.data.table更新版本中, 您将可以直接执行此操作 。 如果我理解正确的话,那么@Arun试图实现的就是在不必先melt数据的情况下进行recast ,这就是现在recast所发生的情况,这实质上是melt + dcast操作序列的包装。


而且,为了彻底,这里是tidyr方法:

 library(dplyr) library(tidyr) mydf %>% gather(var, val, transactions:amount) %>% unite(var2, type, var) %>% spread(var2, val) # id expense_amount expense_transactions income_amount income_transactions # 1 20 95 25 100 20 # 2 30 250 45 300 50 

使用data.table v1.9.6 +,我们可以同时投射多个value.var列(也可以在fun.aggregate使用多个聚合函数)。 有关更多信息和示例部分,请参阅?dcast

 require(data.table) # v1.9.6+ dcast(dt, id ~ type, value.var=names(dt)[3:4]) # id transactions_expense transactions_income amount_expense amount_income # 1: 20 25 20 95 100 # 2: 30 45 50 250 300