2014-12-02 32 views
14

Tôi có một tập dữ liệu dài mà tôi muốn làm rộng và tôi tò mò nếu có cách để thực hiện điều này trong một bước bằng cách sử dụng gói định hình lại hoặc tidyr trong R.Tái định hình nhiều giá trị cùng một lúc

khung dữ liệu df trông như thế này:

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

tôi muốn để có được điều này:

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

tôi biết tôi có thể nhận được một phần của con đường đó với reshape2 qua ví dụ:

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

Nhưng có cách nào để định hình lại toàn bộ df trong một lần xử lý cả hai biến "giao dịch" và "số tiền" cùng một lúc không? Và lý tưởng với tên cột mới thích hợp hơn?

Trả lời

26

Trong "reshape2", bạn có thể sử dụng recast (mặc dù theo kinh nghiệm của tôi, đây không phải là chức năng được biết đến rộng rãi).

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 

Bạn cũng có thể sử dụng cơ sở R của 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 

Hoặc, bạn có thể meltdcast, như thế này (ở đây với "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 

Trong các phiên bản sau của dcast.data.table từ "data.table" (1.9.8) you will be able to do this directly. Nếu tôi hiểu chính xác, những gì @Arun đang cố gắng triển khai sẽ thực hiện định dạng lại mà không cần phải có dữ liệu melt, đó là những gì xảy ra hiện tại với recast, về bản chất là trình bao bọc cho chuỗi hoạt động melt + dcast.


Và, cho triệt để, đây là cách tiếp cận 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

Câu trả lời tuyệt vời. Không biết rằng 'recast' tồn tại. Cảm ơn bạn! – Nikos

+0

Cảm ơn Ananda! Câu trả lời hoàn hảo nếu tôi từng thấy một ... –

+0

Đây là một câu trả lời hay (Enlightened + Huy hiệu câu trả lời hay trên đường đi ...), nhưng không chắc chắn chúng ta cần tất cả những mớ hỗn độn này với 'tidyr',' dplyr', 'data.table',' reshape' vv khi có một cách đơn giản để thực hiện nó với cơ sở R –

5

Với v1.9.6 data.table +, chúng ta có thể đúc nhiều value.var cột cùng một lúc (và cũng có thể sử dụng nhiều chức năng kết hợp trong fun.aggregate) . Vui lòng xem ?dcast để biết thêm và cũng là phần ví dụ.

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 
Các vấn đề liên quan