data.table
cá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?
data.table
cá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:
Đâ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.frame
như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 j
như 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 for
vò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.table
phươ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
, nomatch
vv Vì vậy, đối với bên trong for
vò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 set
bao gồm i
phả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ế đó set
có 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
set(DT, i, "V1", i)
đặt "V1"
cột trong khi set(DT, i, colVar, i)
đặt tên cột có trong colVar
biế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.