Risagoma più valori contemporaneamente

Ho un lungo set di dati che vorrei allargare e sono curioso di sapere se c’è un modo per fare tutto questo in un unico passaggio usando i pacchetti reshape2 o tidyr in R.

Il frame dati df aspetto:

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

Mi piacerebbe arrivare a questo:

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

So che posso ottenere una parte del modo lì con Reshape2 via per esempio:

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

Ma c’è un modo per rimodellare l’intero df in una volta, affrontando contemporaneamente le variabili “transaction” e “amount”? E idealmente con nuovi nomi di colonne più appropriati?

In “reshape2”, puoi usare recast (sebbene nella mia esperienza, questa non sia una funzione ampiamente conosciuta).

 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 

Puoi anche usare la reshape base R:

 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 

Oppure puoi melt e dcast , come questo (qui con “data.table”):

 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 

Nelle versioni successive di dcast.data.table da “data.table” (1.9.8) sarete in grado di farlo direttamente . Se ho capito bene, ciò che @Arun sta cercando di implementare sarebbe eseguire la rimodulazione senza prima dover melt i dati, che è ciò che accade attualmente con la recast , che è essenzialmente un wrapper per una sequenza di operazioni di melt + dcast .


E, per completezza, ecco l’approccio 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 

Con data.table v1.9.6 +, possiamo lanciare contemporaneamente più colonne value.var (e anche utilizzare più funzioni di aggregazione in fun.aggregate ). Si prega di vedere ?dcast per di più e anche la sezione degli esempi.

 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