2009-02-27 31 views
12

Tôi có 12 data.frame s để làm việc. Chúng tương tự nhau và tôi phải thực hiện cùng một quy trình cho mỗi cái, vì vậy tôi đã viết một hàm cần có một data.frame, xử lý nó và sau đó trả về một data.frame. Những công việc này. Nhưng tôi sợ rằng tôi đang đi qua một cấu trúc rất lớn. Tôi có thể làm bản sao tạm thời (tôi?) Điều này không thể hiệu quả. Cách tốt nhất để tránh đi qua một số data.frame là gì?Cách tốt nhất để tránh đi qua một khung dữ liệu xung quanh là gì?

doSomething <- function(df) { 
    // do something with the data frame, df 
    return(df) 
} 
+0

Câu hỏi tiếp theo: Khi kết thúc bằng 'doSomething', lệnh 'rm (doSomething)' sẽ giải phóng đối tượng để thu gom rác, phải không? – bernie

+0

Adam, vâng. Bạn nói đúng. –

+0

nhưng hãy nhớ rằng trong ví dụ trên 'doSomething' là một hàm, không phải dữ liệu, vì vậy nó không phải là rất lớn. –

Trả lời

11

Bạn thực sự đang chuyển đối tượng xung quanh và sử dụng một số bộ nhớ. Nhưng tôi không nghĩ rằng bạn có thể làm một hoạt động trên một đối tượng trong R mà không đi qua các đối tượng xung quanh. Ngay cả khi bạn không tạo ra một hàm và đã thực hiện các hoạt động của bạn bên ngoài hàm, R sẽ hành xử về cơ bản giống nhau.

Cách tốt nhất để thấy điều này là thiết lập một ví dụ. Nếu bạn đang ở trong Windows, hãy mở Windows Task Manager. Nếu bạn đang ở trong Linux mở một cửa sổ đầu cuối và chạy lệnh trên cùng. Tôi sẽ giả sử Windows trong ví dụ này. Trong R chạy như sau:

col1<-rnorm(1000000,0,1) 
col2<-rnorm(1000000,1,2) 
myframe<-data.frame(col1,col2) 

rm(col1) 
rm(col2) 
gc() 

điều này tạo ra một vài vectơ được gọi là col1 và col2 sau đó kết hợp chúng thành khung dữ liệu được gọi là myframe. Sau đó nó sẽ loại bỏ các vectơ và buộc thu gom rác để chạy. Xem trong trình quản lý tác vụ cửa sổ của bạn khi sử dụng mem cho tác vụ Rgui.exe. Khi tôi bắt đầu R nó sử dụng khoảng 19 meg mem. Sau khi tôi chạy các lệnh trên máy tính của tôi đang sử dụng chỉ dưới 35 meg cho R.

Bây giờ thử điều này:

myframe<-myframe+1 

sử dụng bộ nhớ của bạn cho R nên nhảy đến hơn 144 meg. Nếu bạn buộc thu gom rác bằng gc(), bạn sẽ thấy nó giảm xuống còn khoảng 35 meg. Để thử tính năng này bằng chức năng, bạn có thể thực hiện các thao tác sau:

doSomething <- function(df) { 
    df<-df+1-1 
return(df) 
} 
myframe<-doSomething(myframe) 

khi bạn chạy mã ở trên, mức sử dụng bộ nhớ sẽ tăng lên đến 160 meg. Chạy gc() sẽ thả nó trở lại 35 meg.

Vì vậy, những gì để làm cho tất cả điều này? Vâng, thực hiện một thao tác bên ngoài một hàm không hiệu quả hơn nhiều (về mặt bộ nhớ) hơn là thực hiện nó trong một hàm. Bộ sưu tập rác dọn dẹp mọi thứ thật đẹp. Bạn có nên buộc gc() chạy không? Có lẽ không phải vì nó sẽ tự động chạy khi cần thiết, tôi chỉ chạy nó ở trên để cho thấy nó tác động đến việc sử dụng bộ nhớ như thế nào.

Tôi hy vọng điều đó sẽ hữu ích!

8

Tôi không phải là chuyên gia R, nhưng hầu hết các ngôn ngữ đều sử dụng lược đồ tính tham chiếu cho các đối tượng lớn. Một bản sao của dữ liệu đối tượng sẽ không được thực hiện cho đến khi bạn sửa đổi bản sao của đối tượng. Nếu các chức năng của bạn chỉ đọc dữ liệu (tức là để phân tích) thì không nên sao chép.

+3

Đây là cách R hoạt động tốt, Neil. Điểm tốt. –

1

Tôi bắt gặp câu hỏi này đang tìm kiếm thứ gì khác và cũ - vì vậy tôi sẽ chỉ cung cấp câu trả lời ngắn gọn (để lại nhận xét nếu bạn muốn giải thích thêm).

Bạn có thể truyền xung quanh các môi trường trong R chứa bất kỳ vị trí nào từ 1 đến tất cả các biến của bạn. Nhưng có lẽ bạn không cần phải lo lắng về nó.

[Bạn cũng có thể làm điều gì đó tương tự với các lớp học. Hiện tại, tôi chỉ hiểu cách sử dụng các lớp cho các chức năng đa hình - và lưu ý có hơn 1 hệ thống lớp học đá xung quanh.]

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