Khi nào tôi nên sử dụng toán tử: = trong data.table?


88

data.tablecác đối tượng bây giờ có toán tử: =. Điều gì làm cho toán tử này khác với tất cả các toán tử gán khác? Ngoài ra, công dụng của nó là gì, hiệu quả nhanh hơn và khi nào thì nên tránh?

Câu trả lời:


94

Đây là một ví dụ cho thấy 10 phút giảm xuống còn 1 giây (từ TIN TỨC trên trang chủ ). Nó giống như gán phụ cho một data.framenhưng không sao chép toàn bộ bảng mỗi lần.

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

Đưa :=vào jnhư vậy cho phép nhiều thành ngữ hơn:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

và:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

Tôi không thể nghĩ ra bất kỳ lý do nào để tránh :=! Ngoài ra, bên trong một forvòng lặp. Kể từ khi :=xuất hiện bên trong DT[...], nó đi kèm với chi phí nhỏ của [.data.tablephương pháp; ví dụ, S3 công văn và kiểm tra sự hiện diện và loại lập luận như i, by, nomatchvv Vì vậy, đối với bên trong forvòng lặp, có một chi phí thấp, phiên bản trực tiếp :=gọi set. Xem ?setđể biết thêm chi tiết và ví dụ. Nhược điểm của setbao gồm iphải là số hàng (không có tìm kiếm nhị phân) và bạn không thể kết hợp nó với by. Bằng cách đưa ra những hạn chế đó setcó thể giảm chi phí đáng kể.

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018

26
Cảm ơn vì đã phát triển gói này. Tôi có cảm giác rằng tôi sẽ sửa đổi rất nhiều mã của mình để sử dụng gói này.
Lặp lại

1
Mở trò chuyện tôi đã được yêu cầu tự hỏi / câu trả lời (mà dường như được khuyến khích ) - câu hỏi đó là ở đây
Matt Dowle

4
@MatthewDowle Bạn muốn bao gồm giải thích về thời điểm không sử dụng: = và sử dụng set () thay thế?
Ari B. Friedman,

2
@MatthewDowle Tôi sẽ +1 lại nếu có thể.
Ari B. Friedman

3
@jabberwocky Không sao. set(DT, i, "V1", i)đặt "V1"cột trong khi set(DT, i, colVar, i)đặt tên cột có trong colVarbiến (ví dụ: nếu colVar = "V1"được thực hiện trước đó). Các dấu ngoặc kép chỉ ra rằng lấy tên cột theo nghĩa đen thay vì tra cứu biến.
Matt Dowle
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.