2009-12-07 32 views
10

Tôi đang cố gắng định lại khung dữ liệu trong R và có vẻ như có vấn đề khi sử dụng các cách được khuyến nghị làm như vậy. Khung dữ liệu có cấu trúc sau:Hiệu suất R với định dạng lại dữ liệu

ID      DATE1    DATE2   VALTYPE  VALUE 
'abcd1233'   2009-11-12  2009-12-23   'TYPE1'  123.45 
... 

VALTYPE là một chuỗi và là một yếu tố chỉ có 2 giá trị (nói TYPE1TYPE2). Tôi cần phải biến nó thành khung sau dữ liệu ("rộng" transpose) dựa trên ID chung ngày:

ID      DATE1    DATE2   VALUE.TYPE1 VALUE.TYPE2 
'abcd1233'    2009-11-12  2009-12-23  123.45   NA 
... 

khung Dữ liệu có hơn 4.500.000 quan sát (mặc dù khoảng 70% VALUE s là NA). Máy này là một máy trạm Linux dựa trên Intel với 4Gb RAM. Tải dữ liệu (từ một tập tin Rdata nén) vào một quá trình R tươi làm cho nó phát triển đến khoảng 250Mb mà rõ ràng lá rất nhiều không gian để định hình lại.

Đây là những kinh nghiệm của tôi cho đến nay:

  • Sử dụng vani reshape() phương pháp:

    tbl2 < - reshape (tbl, hướng = "rộng", idvar = c ("ID", "DATE1 "," DATE2 "), timevar =" VALTYPE ");

KẾT QUẢ: Error: cannot allocate vector of size 4.8 Gb

  • Sử dụng cast() phương pháp reshape gói:

    tbl2 < - cast (tbl, ID + DATE1 + DATE2 ~ VALTYPE);

KẾT QUẢ: Quá trình R tiêu thụ tất cả RAM không có kết thúc. Đã phải giết quá trình cuối cùng.

  • Sử dụng by()merge():

    sp < - bởi (tbl [c (1,2,3,5)], tbl $ VALTYPE, function (x) x); tbl < - hợp nhất (sp [["TYPE1"]], sp [["TYPE2"]], bởi = c ("ID", "DATE1", "DATE2"), tất cả = TRUE, sort = TRUE) ;

KẾT QUẢ: hoạt động tốt, mặc dù điều này không phải là rất thanh lịch và dễ dàng (nghĩa là nó sẽ bị hỏng nếu có thêm loại).

Để thêm sự xúc phạm đến thương tích, hoạt động được đề cập có thể đạt được một cách trivially trong khoảng 3 dòng AWK hoặc Perl (và hầu như không sử dụng RAM). Vì vậy, câu hỏi đặt ra là: cách tốt hơn để thực hiện thao tác này trong R bằng cách sử dụng các phương pháp được đề xuất mà không tốn tất cả RAM có sẵn là gì?

Trả lời

1

Một mẹo hữu ích là kết hợp các biến id vào một vector ký tự và sau đó thực hiện thay đổi hình.

tbl$NEWID <- with(tbl, paste(ID, DATE1, DATE2, sep=";")) 
tbl2 <- recast(tbl2, NEWID ~ VALTYPE, measure.var="VALUE") 

Tốc độ này nhanh hơn 40% so với kích thước tương tự trong bộ đệm lõi 2.2 của tôi.

+0

Không, bằng cách sử dụng 'recast()' cho thấy cùng một vấn đề như với phương thức 'cast()' ở trên - quá trình đã vượt quá 5 Gb bộ nhớ ảo vì vậy tôi đã giết nó sau khoảng 1 giờ. –

1

Điều gì về cách thực hiện điều này theo cách không giống R? Tôi giả sử bạn có một TYPE1 và một hàng TYPE2 cho mỗi giá trị của ID, DATE1, DATE2? Sau đó, sắp xếp khung dữ liệu theo các biến đó và viết một vòng lặp lớn. Bạn có thể liên tục thực hiện các hoạt động rbind() để xây dựng bảng hoặc bạn có thể cố gắng phân bổ trước bảng (có thể) và chỉ định các vị trí VALUE.TYPE1 và VALUE.TYPE2 với [< -, nên thực hiện nhiệm vụ đó trong địa điểm.

(Lưu ý rằng nếu bạn đang sử dụng rbind(), tôi tin rằng nó không hiệu quả nếu bạn có bất kỳ biến yếu tố, do đó hãy chắc chắn rằng tất cả mọi thứ là một nhân vật thay thế!)

+0

Không có 'rbind' và vòng lặp:' tbl <- tbl [với (tbl, thứ tự (ID, DATE1, DATE2, VALTYPE)),]; tbl_out <- tbl [seq (1, nrow (tbl), theo = 2), - 4]; tên (tbl_out) [4] <- "VALUE.TYPE1"; tbl_out $ VALUE.TYPE2 <- tbl $ VALUE [seq (2, nrow (tbl), by = 2)]; ' – Marek

+0

Chúng tôi không thể giả định rằng có chính xác 2 mục nhập cho mỗi ID/DATE. Điều này sẽ ngay lập tức phá vỡ mã của Marek ở trên. Ngoài ra, nó sẽ còn dễ vỡ hơn mã lệnh 'by()/merge()' đang hoạt động của tôi trong phần nội dung của câu hỏi. Nhìn chung, tôi không có bất kỳ vấn đề gì với cách tiếp cận vòng lặp ngoại trừ việc tôi không hiểu tại sao hàm này dành riêng cho mục đích đó (đó là 'reshape()' không thành công trên một vấn đề tầm thường như vậy) –

1

Có lẽ bạn có thể sử dụng con mèo() chức năng?

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