是否可以通过引用删除data.table
对象?如何实现一个函数 rm_tbl()
,它接受一个 data.table
对象并将 NULL
分配给任何环境中指向该对象的任何名称(这是 globalenv 的后代)?
示例,由于明显的原因不起作用,但也许传达了我想要实现的目标:
rm_tbl_1 <- function(tbl) {
rm(tbl)
invisible(NULL)
}
rm_tbl_2 <- function(tbl) {
tbl <<- NULL
invisible(NULL)
}
以下内容很接近,但有点黑客(它也不会导致 NULL
而是导致零行 data.table
)
rm_tbl_3 <- function(tbl) {
tbl[, colnames(tbl) := rep(list(NULL), ncol(tbl))]
invisible(NULL)
}
为了完整性:
dt <- data.table(a = 1:3, b = 2:4)
rm_tbl_1(dt)
dt
rm_tbl_2(dt)
dt
rm_tbl_3(dt)
dt
编辑
根据@Gregor的赞成建议,一些进一步的解释:我面临的问题是我有一个很大的data.table
。现在,在函数中的某个位置,我对该对象执行一些操作,例如调用 data.table::split() ,我不再需要原始的 data.table 。此外,为了对数据进行进一步转换,我需要原始 data.table
的内存。我该怎么做?
一个例子:
fun_a <- function() {
dt <- data.table(a = 1:2, b = 2:3)
fun_b(dt)
}
fun_b <- function(tbl) {
temp <- split(tbl, by = "b")
rm_dt(tbl)
do_stuff_with_dt(temp)
}
fun_a()
这能澄清事情吗?很抱歉一开始就没有说清楚。
最佳答案
这应该可以解决问题:
rm_dt <- function(name) {
# Get data.table of all data.tables in global environment
tbls <- tables(env=.GlobalEnv, silent=TRUE)
# Look up the externalptr address for each data.table
tbls <- tbls[, .(addr=eval(parse(text=sprintf("data.table::address(%s)", NAME)))),
by = NAME]
# Find all data.tables that have the same externalptr address as the one requested for deletion
to_rm <- tbls[addr == tbls[NAME == name, addr], NAME]
# Delete them
rm(list=to_rm, pos=".GlobalEnv")
}
dt <- data.table(a=1)
dt2 <- dt
dt3 <- data.table(a=1)
rm_dt("dt") # should delete dt and dt2, but not dt3
请注意,这只会删除全局环境中的所有引用,如果您在另一个环境中创建引用,则不会被删除:
dt <- data.table(a=1)
dt2 <- dt
e <- new.env()
e$dt3 <- dt
# dt and dt2 will be removed, but e$dt3 will still exist
rm_dt("dt")
关于r - 通过引用删除整个 data.table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52974000/