Chức năng set
hoặc biểu thức :=
bên trong [.data.table
có nghĩa là dữ liệu có thể được cập nhật theo tham chiếu. Những gì tôi không hiểu rất rõ là cách hành vi này khác với việc phân công lại kết quả của một thao tác với data.frame ban đầu."cập nhật theo tham chiếu" so với bản sao nông
keepcols<-function(DF,cols){
eval.parent(substitute(DF<-DF[,cols,with=FALSE]))
}
keeprows<-function(DF,i){
eval.parent(substitute(DF<-DF[i,]))
}
Vì RHS trong biểu thức <-
là một bản sao cạn của dataframe ban đầu trong các phiên bản gần đây của R, các chức năng này có vẻ khá hiệu quả. Phương thức R cơ bản này khác với phương thức data.table tương đương như thế nào? Sự khác biệt chỉ liên quan đến tốc độ hay sử dụng bộ nhớ? Khi nào sự khác biệt lớn nhất?
Một số điểm chuẩn (tốc độ). Dường như sự khác biệt về tốc độ là không đáng kể khi tập dữ liệu chỉ có hai biến và trở nên lớn hơn với nhiều biến hơn.
library(data.table)
# Long dataset
N=1e7; K=100
DT <- data.table(
id1 = sample(sprintf("id%03d",1:K), N, TRUE),
v1 = sample(5, N, TRUE)
)
system.time(DT[,a_inplace:=mean(v1)])
user system elapsed
0.060 0.013 0.077
system.time(DT[,a_inplace:=NULL])
user system elapsed
0.044 0.010 0.060
system.time(DT <- DT[,c(.SD,a_usual=mean(v1)),.SDcols=names(DT)])
user system elapsed
0.132 0.025 0.161
system.time(DT <- DT[,list(id1,v1)])
user system elapsed
0.124 0.026 0.153
# Wide dataset
N=1e7; K=100
DT <- data.table(
id1 = sample(sprintf("id%03d",1:K), N, TRUE),
id2 = sample(sprintf("id%03d",1:K), N, TRUE),
id3 = sample(sprintf("id%010d",1:(N/K)), N, TRUE),
v1 = sample(5, N, TRUE),
v2 = sample(1e6, N, TRUE),
v3 = sample(round(runif(100,max=100),4), N, TRUE)
)
system.time(DT[,a_inplace:=mean(v1)])
user system elapsed
0.057 0.014 0.089
system.time(DT[,a_inplace:=NULL])
user system elapsed
0.038 0.009 0.061
system.time(DT <- DT[,c(.SD,a_usual=mean(v1)),.SDcols=names(DT)])
user system elapsed
2.483 0.146 2.602
system.time(DT <- DT[,list(id1,id2,id3,v1,v2,v3)])
user system elapsed
1.143 0.088 1.220
Bây giờ tôi hiểu rằng setkey
hoặc X[Y,:=
] không thể được thể hiện trong nhiệm kỳ bản sao cạn - vì vậy tôi thực sự chỉ là hỏi về tạo/xóa cột mới hoặc các hàng.