2012-06-14 46 views
23

Tôi có một số data.frame trong R với 19 triệu hàng và 90 cột. Tôi có rất nhiều phụ tùng RAM và chu kỳ CPU. Dường như việc thay đổi một tên cột trong khung dữ liệu này là một hoạt động rất mãnh liệt đối với R.Tại sao thay đổi tên cột mất một thời gian rất dài với một data.frame lớn?

system.time(colnames(my.df)[1] <- "foo") 
    user system elapsed 
356.88 16.54 373.39 

Tại sao lại như vậy? Mỗi hàng có lưu trữ tên cột bằng cách nào đó không? Điều này có tạo ra một khung dữ liệu hoàn toàn mới không? Có vẻ như hoạt động này sẽ hoàn thành trong thời gian không đáng kể. Tôi không thấy điều gì rõ ràng trong số R manual entry.

Tôi đang chạy xây dựng 7600 của R (64bit) trên Windows 7 và trong không gian làm việc hiện tại của tôi, đặt các tên màu trên một data.frame nhỏ mất thời gian '0' theo system.time().

Chỉnh sửa: Tôi biết khả năng sử dụng data.table và, thành thật mà nói, tôi có thể đợi 5 phút để đổi tên hoàn tất trong khi tôi lấy một ít trà. Điều tôi quan tâm là điều gì đang xảy ra và tại sao?

+0

Thật kỳ lạ, tôi chỉ đọc về điều này. Tôi tin rằng nó thực sự có thể được sao chép df _twice_. Nếu bạn đang sử dụng 2.15.0, hãy thử cài đặt và tải gói ** dataframe ** và xem có giúp gì không. – joran

+5

Matthew Dowle giải thích điều này rất độc đáo [ở đây] (http://stackoverflow.com/questions/10655438/rename-one-named-column-in-r/10655997#10655997) và cung cấp một giải pháp với gói 'data.table' . – Chase

+0

Cảm ơn, tôi đã sử dụng 'data.table' khá nhiều (và mắc nợ Matthew Dowle vì đã khiến tôi rơi vào tình huống dính!) - ở đây tôi đã giải thích về những gì đang xảy ra ... và lý tưởng tại sao. Câu trả lời có thực sự chỉ là "data.frame bị mã hóa sai" không? – Ina

Trả lời

21

Như nhiều nhà bình luận đã đề cập, việc đổi tên cột khung dữ liệu chậm, bởi vì (tùy thuộc vào cách bạn thực hiện), nó tạo ra từ 1 đến 4 bản sao của toàn bộ dữ liệu.frame. Ở đây, từ 's trang trợ giúp data.table?setkey, là con đường đẹp nhất của chứng minh hành vi này mà tôi đã nhìn thấy:

DF = data.frame(a=1:2,b=3:4)  # base data.frame to demo copies 
try(tracemem(DF))     # try() for non-Windows where R is 
            # faster without memory profiling 
colnames(DF)[1] <- "A"    # 4 copies of entire object 
names(DF)[1] <- "A"    # 3 copies of entire object 
names(DF) <- c("A", "b")   # 1 copy of entire object 
`names<-`(DF,c("A","b"))   # 1 copy of entire object 
x=`names<-`(DF,c("A","b"))   # still 1 copy (so not print method) 
# What if DF is large, say 10GB in RAM. Copy 10GB just to change a column name? 

Để (bắt đầu) tìm hiểu lý do tại sao mọi thứ được thực hiện theo cách này, có thể bạn sẽ cần để nghiên cứu một số cuộc thảo luận có liên quan về R-devel. Dưới đây là một vài: R-devel: speeding up perceptionR-devel: Confused about NAMES

đọc ấn tượng của tôi về những chủ đề là:

  1. Ít nhất một bản sao được thực hiện để sửa đổi nó có thể được 'thử' trước khi ghi đè lên bản gốc. Do đó, nếu có điều gì đó sai với giá trị được gán lại, [<-.data.frame hoặc names<- có thể 'quay trở lại' và gửi thông báo lỗi mà không làm hỏng bất kỳ đối tượng gốc nào.

  2. Một số thành viên của R-core không hoàn toàn hài lòng với cách mọi thứ đang hoạt động ngay bây giờ. Một số người giải thích rằng trong một số trường hợp "R mất theo dõi"; Luke Tierney chỉ ra rằng ông đã thử một số sửa đổi liên quan đến việc sao chép này trong quá khứ "trong một vài trường hợp và luôn phải quay trở lại"; và Simon Urbanek gợi ý rằng "có thể có một số điều sắp tới, quá"

(Như tôi đã nói, tuy nhiên, đó chỉ là ấn tượng: Tôi chỉ đơn giản là không thể làm theo một cuộc trò chuyện đầy đủ về các chi tiết của R của internals)


Cũng liên quan, trong trường hợp bạn chưa nhìn thấy nó, dưới đây là cách một cái gì đó giống như names(z)[3] <- "c2" "thực sự" làm việc:

# From ?names<- 
z <- "names<-"(z, "[<-"(names(z), 3, "c2")) 

Lưu ý: Phần lớn câu trả lời này đến từ câu trả lời của Matthew Dowle cho this other question. (Tôi nghĩ rằng nó là giá trị đặt nó ở đây, và cho nó một số tiếp xúc nhiều hơn, vì nó có liên quan đến câu hỏi của riêng bạn).

+1

++ để phân tích cú pháp các chủ đề R-devel, tôi đã có một khoảng thời gian khó khăn để bao quanh đầu những cuộc trò chuyện đó. – Ina

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