2012-02-29 25 views
11

Tôi có một khung dữ liệu lớn chiếm khoảng 900MB ram. Sau đó, tôi đã cố gắng để sửa đổi nó như thế này:Hết bộ nhớ khi sửa đổi một tệp dữ liệu lớn R.

dataframe[[17]][37544]=0 

Dường như làm cho R sử dụng nhiều hơn ram 3G và R than phiền: (. Tôi đang trên một máy 32bit) "Lỗi không thể phân bổ vector kích thước 3,0 Mb",

tôi thấy cách này là tốt hơn:

dataframe[37544, 17]=0 

nhưng dấu chân R vẫn tăng lên gấp đôi và lệnh mất khá nhiều thời gian để chạy.

Từ nền C/C++, tôi thực sự bối rối về hành vi này. Tôi nghĩ rằng một cái gì đó như dataframe[37544, 17]=0 nên được hoàn thành trong nháy mắt mà không cần tốn thêm bất kỳ bộ nhớ nào (chỉ cần thay đổi một ô). R đang làm gì cho những lệnh mà tôi đã đăng? Cách đúng để sửa đổi một số phần tử trong một khung dữ liệu là gì mà không cần tăng gấp đôi bộ nhớ?

Cảm ơn bạn rất nhiều vì đã giúp đỡ!

Tao

+3

(Cơ sở) R không nổi tiếng khi xử lý các cấu trúc dữ liệu lớn. Bạn sẽ muốn xem xét một số kết hợp của các gói ** ff **, ** bigmemory ** và ** data.table **. – joran

+3

Điều đó không thực sự đúng - data.frames nổi tiếng không hiệu quả, nhưng có những cấu trúc rất hiệu quả trong (cơ sở) R mà bạn nên sử dụng thay vào đó nếu bạn quan tâm đến hiệu quả. –

+0

@SimonUrbanek Vâng, tôi đã nói rất tệ. Tôi chỉ có nghĩa là chính xác những gì bạn nói, các khung dữ liệu có xu hướng không hiệu quả và các gói tôi đề cập thường có thể hữu ích cho những người xử lý dữ liệu lớn. – joran

Trả lời

8

Tra cứu 'copy-on-write' trong ngữ cảnh của các cuộc thảo luận R liên quan đến bộ nhớ. Ngay sau khi một phần của cấu trúc dữ liệu (có khả năng thực sự lớn) thay đổi, một bản sao được thực hiện.

Một nguyên tắc hữu ích của ngón tay cái là nếu đối tượng lớn nhất của bạn là N mb/gb/... lớn, bạn cần khoảng 3 * N RAM. Đó là cuộc sống với một hệ thống thông dịch.

Năm trước, khi tôi phải xử lý một lượng lớn dữ liệu trên các máy có (tương đối với khối lượng dữ liệu) các máy 32 bit ram tương đối thấp, tôi đã sử dụng tốt các phiên bản đầu tiên của gói bigmemory. Nó sử dụng giao diện 'con trỏ bên ngoài' để giữ bộ nhớ lớn bên ngoài R. Điều đó giúp bạn tiết kiệm không chỉ yếu tố '3x', nhưng có thể nhiều hơn khi bạn có thể thoát khỏi bộ nhớ không tiếp giáp (đó là điều R khác thích).

+0

Cảm ơn rất nhiều! Tôi đã khám phá một số tùy chọn được đề cập trong các câu trả lời. Tôi thấy bigmemory khá dễ dàng với bạn và đủ cho tôi. – agmao

+7

@agmao Hoặc bạn có thể thử ': =' trong 'data.table' để thực hiện chính xác những gì bạn muốn. –

7

Khung dữ liệu là cấu trúc tồi tệ nhất mà bạn có thể chọn sửa đổi. Do xử lý phức tạp tất cả các tính năng (chẳng hạn như giữ tên hàng trong đồng bộ, kết hợp từng phần, v.v.) được thực hiện trong mã R thuần (không giống như hầu hết các đối tượng khác có thể đi thẳng đến C), chúng có xu hướng ép buộc các bản sao bổ sung bạn không thể chỉnh sửa chúng tại chỗ. Kiểm tra R-devel trên các cuộc thảo luận chi tiết về điều này - nó đã được thảo luận trong nhiều lần.

Quy tắc thực tế là không bao giờ sử dụng khung dữ liệu cho dữ liệu lớn, trừ khi bạn xử lý chúng chỉ đọc. Bạn sẽ được đơn đặt hàng của cường độ hiệu quả hơn nếu bạn làm việc trên vectơ hoặc ma trận.

4

Có loại đối tượng được gọi là ffdf trong gói ff về cơ bản là data.frame được lưu trữ trên đĩa. Ngoài các mẹo khác ở trên, bạn có thể thử điều đó.

Bạn cũng có thể thử gói RSQLite.

12

Theo dõi trên Joran đề xuất data.table, dưới đây là một số liên kết. Đối tượng của bạn, ở 900MB, có thể quản lý trong RAM ngay cả trong 32 bit R, không có bản sao nào cả.

When should I use the := operator in data.table?

Why has data.table defined := rather than overloading <-?

Ngoài ra, data.table v1.8.0 (chưa vào cran nhưng ổn định trên R-Forge) có chức năng set() cung cấp phân thậm chí nhanh hơn đến các yếu tố, càng nhanh càng tốt để phân matrix (thích hợp để sử dụng các vòng lặp trong ví dụ). Xem latest NEWS để biết thêm chi tiết và ví dụ. Xem thêm ?":=" được liên kết từ ?data.table.

Và, đây là 12 questions trên Stack Overflow với thẻ data.table chứa từ "reference".

Đối với đầy đủ:

require(data.table) 
DT = as.data.table(dataframe) 
# say column name 17 is 'Q' (i.e. LETTERS[17]) 
# then any of the following : 

DT[37544, Q:=0]    # using column name (often preferred) 

DT[37544, 17:=0, with=FALSE] # using column number 

col = "Q" 
DT[37544, col:=0, with=FALSE] # variable holding name 

col = 17 
DT[37544, col:=0, with=FALSE] # variable holding number 

set(DT,37544L,17L,0)   # using set(i,j,value) in v1.8.0 
set(DT,37544L,"Q",0) 

Nhưng, xin đừng xem các câu hỏi liên quan và tài liệu của gói để xem cách := tổng quát hơn ví dụ đơn giản này; ví dụ: kết hợp := với tìm kiếm nhị phân trong tham gia i.

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