2013-08-04 34 views
11
> library(data.table) 
> A <- data.table(x = c(1,1,2,2), y = c(1,2,1,2), v = c(0.1,0.2,0.3,0.4)) 
> A 
    x y v 
1: 1 1 0.1 
2: 1 2 0.2 
3: 2 1 0.3 
4: 2 2 0.4 
> B <- dcast(A, x~y) 
Using v as value column: use value.var to override. 
> B 
    x 1 2 
1 1 0.1 0.2 
2 2 0.3 0.4 

Dường như tôi có thể định hình lại dữ liệu. Có thể từ dài đến rộng bằng cách sử dụng f.x. dcast của package reshape2. Nhưng data.table đi cùng với một toán tử khung quá tải cung cấp các tham số như 'by' và 'group', điều này khiến tôi tự hỏi liệu nó có thể đạt được nó bằng cách sử dụng hàm này (với chức năng cụ thể của data.table) không?Định hình lại dữ liệu có cấu trúc dài. Có thể vào cấu trúc rộng bằng chức năng data.table?

Chỉ cần một ngẫu nhiên ví dụ từ hướng dẫn:

DT[,lapply(.SD,sum),by=x] 

Điều đó có vẻ tuyệt vời - nhưng tôi không hoàn toàn hiểu được việc sử dụng được nêu ra.

Tôi không tìm thấy một cách hay ví dụ cho điều này vì vậy có lẽ nó chỉ là không thể có thể nó thậm chí không phải là - vì vậy, một "nhất định" không, là không thể vì ... " cũng là một câu trả lời hợp lệ.

+0

Vui lòng xem [tại đây] (http://stackoverflow.com/questions/15510566/nested-if-else-statements-over-a-number-of-columns/15511689?noredirect=1#comment21968080_15511689). – Metrics

+0

Xin lỗi, tôi không thấy điều này liên quan đến câu hỏi của tôi như thế nào. Cũng nên nhớ rằng các hạng mục cột của B tự động phụ thuộc vào A vì vậy số lượng giá trị của 'y' có thể khác nhau tùy từng trường hợp. – Raffael

Trả lời

15

tôi sẽ chọn một ví dụ với nhóm không đồng đều do đó nó dễ dàng hơn để minh họa cho trường hợp tổng quát:

A <- data.table(x=c(1,1,1,2,2), y=c(1,2,3,1,2), v=(1:5)/5) 
> A 
    x y v 
1: 1 1 0.2 
2: 1 2 0.4 
3: 1 3 0.6 
4: 2 1 0.8 
5: 2 2 1.0 

Bước đầu tiên là để lấy số lượng phần tử/mục nhập cho mỗi nhóm "x" giống nhau. Ở đây, với x = 1 có 3 giá trị y, nhưng chỉ có 2 cho x = 2. Vì vậy, chúng ta sẽ phải sửa đầu tiên với NA cho x = 2, y = 3.

setkey(A, x, y) 
A[CJ(unique(x), unique(y))] 

Bây giờ, để có được nó sang định dạng rộng, chúng ta nên nhóm bằng "x" và sử dụng as.list trên v như sau:

out <- A[CJ(unique(x), unique(y))][, as.list(v), by=x] 
    x V1 V2 V3 
1: 1 0.2 0.4 0.6 
2: 2 0.8 1.0 NA 

Bây giờ, bạn có thể đặt tên của các cột reshaped sử dụng tài liệu tham khảo với setnames như sau:

setnames(out, c("x", as.character(unique(A$y))) 

    x 1 2 3 
1: 1 0.2 0.4 0.6 
2: 2 0.8 1.0 NA 
+0

Thực ra giải pháp đầu tiên của bạn không được đưa ra trong bài đăng của bạn. Vì vậy, tôi sẽ giữ nó vì lý do học tập! Cảm ơn rất nhiều vì nỗ lực này! – Raffael

+0

Giải pháp đầu tiên hoạt động khi có các hàng đã bằng nhau cho mỗi nhóm. Và tốt hơn hết là đặt tên cột một lần ở cuối thay vì đặt nó cho mỗi nhóm (đó là giải pháp cũ). Có thể có các vấn đề hiệu suất do đó trên dữ liệu lớn hơn. – Arun

+1

Được rồi, giải pháp này tôi đã tìm thấy sau khi nghiên cứu hướng dẫn trong tuần tôi đoán ... vì vậy, điều này có thể rất chủ quan nhưng tôi nghĩ tôi có thể nói với một số quyền rằng giải pháp này khá phức tạp và phức tạp - không nghi ngờ gì về điều đó nó là giải pháp đơn giản nhất có thể chỉ bằng cách sử dụng data.table như tôi đã yêu cầu. Vì vậy, tôi muốn biết từ bạn cho dù khu vực này có thể định hình lại các tập hợp dữ liệu không chỉ là dữ liệu mà data.table thực sự phải giải quyết. Bạn sẽ vẽ đường về việc sử dụng dữ liệu hợp lý và kinh tế ở đâu và ở đâu để sử dụng các công cụ khác? – Raffael

2

(với các khoản tín dụng để Arun)

A[, setattr(as.list(v), 'names', y), by=x] 
+0

chúng tôi có một thỏa thuận ở đây! – Raffael

+0

Lỗi trong '[.data.table' (A,, setattr (as.list (v)," tên ", y), theo = x): j không đánh giá cùng một số cột cho mỗi nhóm – skan

10

Sử dụng dcast() (bây giờ là một phương pháp mặc định data.table, từ phiên bản 1.9 .5; phiên bản trước sử dụng dcast.data.table) như trong

> dcast(A,x~y) 
Using 'v' as value column. Use 'value.var' to override 
    x 1 2 3 
1: 1 0.2 0.4 0.6 
2: 2 0.8 1.0 NA 

này là nhanh chóng và obviates sự cần thiết để setnames().

Điều này cũng đặc biệt hữu ích khi y trong ví dụ trên là biến yếu tố với các mức ký tự - ví dụ: 'Thấp', 'Trung bình', 'Cao' - bởi vì CJ() không thể trả lại dữ liệu rộng với các biến theo thứ tự mà setnames() mong đợi và bạn có thể kết thúc với dữ liệu của bạn bị gắn nhãn sai.

+0

+1. Cảm ơn bạn đã cập nhật câu trả lời này với 'dcast.data.table'. – Arun

Các vấn đề liên quan