2010-09-30 37 views
11

Giả sử (để đơn giản hóa) Tôi có một bảng có chứa một số kiểm soát so với dữ liệu xử lý:hàng Xoay vòng vào cột

Which, Color, Response, Count 
Control, Red, 2, 10 
Control, Blue, 3, 20 
Treatment, Red, 1, 14 
Treatment, Blue, 4, 21 

Đối với mỗi màu sắc, tôi muốn có một hàng duy nhất với dữ liệu kiểm soát và điều trị, ví dụ:

Color, Response.Control, Count.Control, Response.Treatment, Count.Treatment 
Red, 2, 10, 1, 14 
Blue, 3, 20, 4, 21 

Tôi đoán một cách để làm điều này là sử dụng kết hợp nội bộ trên mỗi tập con điều khiển/điều trị (hợp nhất trên cột Màu), nhưng có cách nào tốt hơn không? Tôi đã nghĩ rằng gói reshape hoặc chức năng ngăn xếp bằng cách nào đó có thể làm điều đó, nhưng tôi không chắc chắn.

+2

Nếu bạn tạo một data.frame hoàn toàn khả thi với một cái gì đó giống như d.put (đầu (df, 20)) nó hoạt động kỳ diệu cho những người trong chúng ta cố gắng để trả lời –

Trả lời

17

Sử dụng gói định hình lại.

Thứ nhất, làm tan chảy data.frame của bạn:

x <- melt(df) 

Sau đó đúc:

dcast(x, Color ~ Which + variable) 

Tùy thuộc vào phiên bản của gói Reshape bạn đang làm việc với nó có thể là cast() (reshape) hoặc dcast() (reshape2)

Thì đấy.

6

Chức năng cast từ gói reshape (không bị nhầm lẫn với hàm reshape trong cơ sở R) có thể thực hiện việc này và nhiều thứ khác. Xem tại đây: http://had.co.nz/reshape/

+0

Ồ, vâng, tôi có nghĩa là gói định hình lại. Tôi đã không chắc chắn làm thế nào để sử dụng diễn viên để làm những gì tôi muốn, mặc dù? Một cách gần là bằng cách thực hiện phép đúc (dữ liệu, vị trí ~ biến | trong đó), nhưng điều này đặt điều khiển/điều trị trong một danh sách, chứ không phải trong các cột. – grautur

+0

Tôi không nhớ chính xác, nhưng tôi khá chắc chắn tài liệu của gói định hình lại có ví dụ về việc thực hiện chính xác điều này. Bạn phải nói với nó cách bạn muốn các tên cột được xây dựng. – zwol

3

Định dạng lại thực sự hoạt động để xoay vòng khung dữ liệu gầy (ví dụ: từ truy vấn SQL đơn giản) thành ma trận rộng và rất linh hoạt nhưng chậm. Đối với số lượng lớn dữ liệu, rất rất chậm. May mắn thay, nếu bạn chỉ muốn xoay quanh một hình dạng cố định, nó khá dễ dàng để viết một hàm C nhỏ để làm trục nhanh.

Trong trường hợp của tôi, xoay vòng một khung dữ liệu gầy với 3 cột và 672,338 hàng mất 34 giây với reshape, 25 giây với mã R của tôi, và 2,3 giây với C. Trớ trêu thay, việc thực hiện C có lẽ dễ dàng hơn để viết hơn (điều chỉnh tốc độ) R thực hiện.

Đây là mã C cốt lõi để chia số điểm nổi. Lưu ý rằng nó giả định rằng bạn đã phân bổ một ma trận kết quả có kích thước đúng trong R trước gọi mã C, gây ra các folks R-devel rùng mình kinh hãi:

#include <R.h> 
#include <Rinternals.h> 
/* 
* This mutates the result matrix in place. 
*/ 
SEXP 
dtk_pivot_skinny_to_wide(SEXP n_row ,SEXP vi_1 ,SEXP vi_2 ,SEXP v_3 ,SEXP result) 
{ 
    int ii, max_i; 
    unsigned int pos; 
    int nr = *INTEGER(n_row); 
    int * aa = INTEGER(vi_1); 
    int * bb = INTEGER(vi_2); 
    double * cc = REAL(v_3); 
    double * rr = REAL(result); 
    max_i = length(vi_2); 
    /* 
    * R stores matrices by column. Do ugly pointer-like arithmetic to 
    * map the matrix to a flat vector. We are translating this R code: 
    * for (ii in 1:length(vi.2)) 
    *  result[((n.row * (vi.2[ii] -1)) + vi.1[ii])] <- v.3[ii] 
    */ 
    for (ii = 0; ii < max_i; ++ii) { 
     pos = ((nr * (bb[ii] -1)) + aa[ii] -1); 
     rr[pos] = cc[ii]; 
     /* printf("ii: %d \t value: %g \t result index: %d \t new value: %g\n", ii, cc[ii], pos, rr[pos]); */ 
    } 
    return(result); 
} 
+0

Bạn có thể cung cấp các ví dụ không? –

+0

Tôi nên làm sạch mã pivot của mình và đặt nó vào một gói R độc lập, nhưng không bao giờ ... :(Mã C lõi là khá đơn giản, tôi vừa thêm phiên bản dấu chấm động vào bài đăng gốc ở trên. Mã R tôi sử dụng để lái xe phức tạp hơn một chút (và bao gồm rất nhiều nội dung cụ thể cho môi trường của tôi) .Lập các tên mờ, chuỗi trụ bằng cách chuyển đổi từ/sang các số nguyên, v.v. – atp

6

Để thêm vào các tùy chọn (nhiều năm sau) ....

Cách tiếp cận điển hình trong cơ sở R sẽ liên quan đến hàm reshape (thường không được ưa chuộng vì vô số các đối số mất thời gian để làm chủ). Đó là một chức năng khá hiệu quả cho các tập dữ liệu nhỏ hơn, nhưng không phải lúc nào cũng có quy mô tốt.

reshape(mydf, direction = "wide", idvar = "Color", timevar = "Which") 
# Color Response.Control Count.Control Response.Treatment Count.Treatment 
# 1 Red    2   10     1    14 
# 2 Blue    3   20     4    21 

Đã bao phủ là cast/dcast từ "định hình lại" và "reshape2" (và bây giờ, dcast.data.table từ "data.table", đặc biệt hữu ích khi bạn có bộ dữ liệu lớn).Nhưng cũng từ Hadleyverse, có "tidyr", trong đó hoạt động độc đáo với "dplyr" gói:

library(tidyr) 
library(dplyr) 
mydf %>% 
    gather(var, val, Response:Count) %>% ## make a long dataframe 
    unite(RN, var, Which) %>%    ## combine the var and Which columns 
    spread(RN, val)      ## make the results wide 
# Color Count_Control Count_Treatment Response_Control Response_Treatment 
# 1 Blue   20    21    3     4 
# 2 Red   10    14    2     1 

Cũng cần lưu ý sẽ là trong một phiên bản sắp tới của "data.table", các dcast.data.table chức năng sẽ có thể xử lý điều này mà không cần phải đầu tiên melt dữ liệu của bạn.

Việc thực hiện data.table của dcast cho phép bạn chuyển đổi nhiều cột sang một định dạng rộng mà không tan chảy nó lần đầu tiên, như sau:

library(data.table) 
dcast(as.data.table(mydf), Color ~ Which, value.var = c("Response", "Count")) 
# Color Response_Control Response_Treatment Count_Control Count_Treatment 
# 1: Blue    3     4   20    21 
# 2: Red    2     1   10    14 
+1

Cảm ơn bạn đã thay đổi hình mẫu. tin rằng ví dụ 'reshape' của bạn cùng với câu hỏi ban đầu sẽ được thêm vào tài liệu chính thức của chức năng' reshape'. – user1700890

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