【发布时间】:2017-08-01 10:13:25
【问题描述】:
与How to use data.table within functions and loops?相关,有没有更好的方法来做如下所示的功能,具体使用data.table?
注意:下面的所有代码都可以正常工作,但是......速度很慢。
(我使用简单的“清理”步骤来演示问题)。
目标是编写一个函数,1) 有效地 2) 替换 3) 一些 data.table 中的值,以便它然后可以在循环中使用以清理大量数据集。
在 C++ 中,这将使用指针和引用调用来完成,如下所示:
void cleanDT(* dataTable dt); cleanDT(&dt222)
然而,在 R 中,每次调用函数时,我们都会来回复制整个数据集 (data.tables)。
cleanDT <- function (dt) {
strNames <- names(dt); nCols <- 1:length(strNames)
for (i in nCols) {
strCol <- strNames[i]
if ( class(dt[[strCol]]) == "numeric" )
dt[[strCol]] <- floor(dt[[strCol]])
else
dt[[strCol]] <- gsub("I", "i", dt[[strCol]])
}
return(dt)
}
cleanDTByReference <- function (dt) {
dtCleaned <- dt
strNames <- names(dt); nCols <- 1:length(strNames)
for (i in nCols) {
strCol = strNames[i]
if ( class(dt[[strCol]]) == "numeric" )
dtCleaned[[strCol]] <- floor(dt[[strCol]])
else
dtCleaned[[strCol]] <- gsub("I", "i", dt[[strCol]])
}
eval.parent(substitute(dt <- dtCleaned))
}
dt222 <- data.table(ggplot2::diamonds); dt222[1:2]
dt222 <- cleanDT(dt222); dt222[1:2]
dt222 <- data.table(diamonds); dt222[1:2]
# carat cut color clarity depth table price x y z
#1: 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
#2: 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
cleanDTByReference(dt222); dt222[1:2]
# carat cut color clarity depth table price x y z
#1: 0 ideal E Si2 61 55 326 3 3 2
#2: 0 Premium E Si1 59 61 326 3 3 2
然后我们将使用这个函数在这样的循环中清理数据表列表:
dt333 <- data.table(datasets::mtcars)
listDt <- list(dt222, dt333)
for(dt in listDt) {
print(dt[1:2])
cleanDTByReference(dt); print(dt[1:2])
}
因此,理想情况下,我希望使用函数以这种方式“清理”我的所有数据表。但目前不使用引用,上面的代码实际上并没有改变listDt,也没有改变dt222,dt333。
你能建议如何实现吗?
【问题讨论】:
-
如果您阅读 data.table 包的小插图,他们将介绍几种通过引用进行修改的方法。在 data.tables 的意义上,您的函数不会通过引用进行修改。
标签: r function pointers data.table pass-by-reference