2014-12-02 28 views
14

Ho una serie di dati a lungo Vorrei fare largo e io sono curioso di sapere se c'è un modo per fare tutto questo in un unico passaggio utilizzando i pacchetti reshape2 o tidyr in R.Rimodellare valori multipli in una sola volta

la cornice di dati df assomiglia a questo:

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 di poter ottenere una parte della strada lì con reshape2 via per esempio:

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

Ma c'è un modo per rimodellare l'intero df in un colpo indirizzando contemporaneamente le variabili "transazioni" e "importo"? E idealmente con nuovi nomi di colonne più appropriati?

risposta

26

In "reshape2", è possibile utilizzare recast (sebbene nella mia esperienza, questa non è una funzione ampiamente nota).

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 

È inoltre possibile utilizzare la base di 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 

In alternativa, è possibile 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 

In versioni successive di dcast.data.table da "data.table" (1.9.8) you will be able to do this directly. Se ho capito bene, ciò che @Arun sta cercando di implementare sarebbe quello di fare il rimodellamento senza prima avere a melt i dati, che è ciò che accade attualmente con recast, che è essenzialmente un wrapper per una sequenza di operazioni 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 
+0

Sorprendente risposta. Non sapevo che esistesse 'rifusione'. Grazie! – Nikos

+0

Grazie Ananda! Risposta perfetta se ne ho mai visto uno ... –

+0

Questa è una bella risposta (distintivi di risposta Enlightened + Nice sulla strada ...), ma non sono sicuro di cosa abbiamo bisogno di tutto questo casino con 'tidyr',' dplyr', 'data.table',' reshape' ecc. quando c'è un modo così semplice di farlo con la base R –

5

Con v1.9.6 data.table +, siamo in grado di lanciare multipla value.var colonne contemporaneamente (e utilizzare anche più funzioni di aggregazione in fun.aggregate) . Si prega di vedere ?dcast per ulteriori 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 
Problemi correlati