【发布时间】:2018-03-18 09:22:21
【问题描述】:
在许多情况下,当我需要使用变量中传递的名称来寻址列时,我会看到以下两个选项:myDT[[myCol]] 或 myDT[,get(myCol)],例如:
# get() ####
cast_num_get <- function(inpDT, cols2cast){
for (thisCol in cols2cast){
inpDT[, (thisCol):=as.numeric(get(thisCol))]
}
return(inpDT);
}
# [[ ####
cast_num_b <- function(inpDT, cols2cast){
for (thisCol in cols2cast){
inpDT[[thisCol]] <- inpDT[[thisCol]]
}
return(inpDT);
}
# two more options added from the comments:
# lapply(.SD) ####
cast_num_apply <- function(inpDT, cols2cast){
inpDT[, (cols2cast) := lapply(.SD, as.numeric), .SDcols = cols2cast]
return(inpDT);
}
# set() ####
cast_num_for_set <- function(inpDT, cols2cast){
for (thisCol in cols2cast){
set(inpDT, j = thisCol, value = as.numeric(inpDT[[thisCol]]))
}
return(inpDT);
}
【问题讨论】:
-
在这个例子中,
inpDT[, (cols2cast) := lapply(.SD, as.numeric), .Sdcols = cols2cast]imo 会比你展示的两个选项中的任何一个都好。 -
另外,如果您已经使用 for 循环,请使用
set而不是`[.data.table`。除了:=是通过引用分配的,而[[是原始的并且非常轻量级(尽管可能会复制 - 至少是一个浅的)。get通常效率很低,在 data.table 环境中工作时通常有更好的选择。 -
您没有显示任何基准,但我怀疑您的基准测试不正确。 [[ 应该比进入 [ 更快,即使只是因为它是一个函数调用而不是两个调用。
-
你的
cast_num_b-option 有一个不公平的优势:它什么也没做。而不是inpDT[[thisCol]] <- inpDT[[thisCol]],您应该在该函数中使用inpDT[[thisCol]] <- as.numeric(inpDT[[thisCol]])。还添加了一个答案,比较了不同的方法和一些解释。
标签: r data.table