2014-12-02 11 views
14

mam długiego zestawu danych chciałbym, aby szeroko i jestem ciekaw, czy istnieje sposób, aby zrobić to wszystko w jednym kroku przy użyciu pakietów reshape2 lub tidyr w R.zmienią wiele wartości na raz

ramka danych df wygląda następująco:

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

Chciałbym dostać się do tego:

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

wiem, że mogę dostać część drogi tam z reshape2 poprzez na przykład:

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

Ale czy istnieje sposób na przekształcenie całego pliku df w jednym ujęciu, zaadresowanie jednocześnie zmiennych "transakcje" i "ilość"? A najlepiej z nowszymi bardziej odpowiednimi nazwami kolumn?

Odpowiedz

26

W "reshape2" można użyć recast (choć z mojego doświadczenia wynika, że ​​nie jest to funkcja powszechnie znana).

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 

Można również użyć baza 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 

Albo można melt i dcast, tak (tu z "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 

W nowsze wersje dcast.data.table z "data.table" (1.9.8) you will be able to do this directly. Jeśli dobrze zrozumiem, to, co @Arun będzie próbowało zaimplementować, będzie dokonywało zmiany kształtu bez wcześniejszego uzyskania danych z melt, co dzieje się obecnie z recast, która jest w zasadzie opakowaniem dla sekwencji operacji melt + dcast.


A dla dokładności, oto podejście 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

Niesamowita odpowiedź. Nie wiedziałem, że istnieje "przekształcenie". Dziękuję Ci! – Nikos

+0

Dzięki Ananda! Doskonała odpowiedź, jeśli kiedykolwiek widziałem ... –

+0

To jest miła odpowiedź (Odznaki odznaczenia + Oświecenie + Nicea po drodze ...), ale nie jestem pewien, czego potrzebujemy cały ten bałagan z 'tidyr',' dplyr', 'data.table',' reshape' itp. kiedy jest tak prosty sposób zrobienia tego z bazą R –

5

Z data.table v1.9.6 +, możemy rzucić stwardnienie value.var kolumn jednocześnie (a także korzystać z wielu funkcji agregacji w fun.aggregate) . Więcej informacji znajduje się na stronie ?dcast, a także w sekcji przykładów.

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