r - 通过引用分配到加载的包装数据集中

标签 r data.table

我正在创建一个使用data.table作为数据集的程序包,并具有使用:=通过引用分配的几个功能。

我已经构建了一个简单的程序包来演示我的problem

 library(devtools)
 install_github('foo','mnel')


它包含两个功能

foo <- function(x){
  x[, a := 1]
}
fooCall <- function(x){
  eval(substitute(x[, a :=1]),parent.frame(1))
} 


和使用创建的数据集(非延迟加载)DT

DT <- data.table(b = 1:5)
save(DT, file = 'data/DT.rda')


安装此软件包时,我的理解是foo(DT)应该在DT中通过引用进行分配。

 library(foo)
 data(DT)
 foo(DT)
   b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1

# However this has not assigned by reference within `DT`

DT
   b
1: 1
2: 2
3: 3
4: 4
5: 5


如果我使用更多的correct

tracmem(DT)
DT <- foo(DT)
# This works without copying
DT 
 b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
untracemem(DT)


如果我在函数中使用evalsubstitute

fooCall(DT)
   b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1
# it does assign by reference 
DT
   b a
1: 1 1
2: 2 1
3: 3 1
4: 4 1
5: 5 1


我应该坚持吗


DT <- foo(DT)eval / substitute路线,或
关于data如何加载数据集,即使不是很懒,我是否还不了解?

最佳答案

这与数据集或锁定无关-您可以简单地使用

DT<-unserialize(serialize(data.table(b = 1:5),NULL))
foo(DT)
DT


我怀疑这与data.table必须在第一次访问DT时必须在对象内部重新创建extptr的事实有关,但它是在副本上执行的,因此无法与在全球环境中独创。



[来自马修]完全正确。

DT<-unserialize(serialize(data.table(b = 1:3),NULL))
DT
   b
1: 1
2: 2
3: 3
DT[,newcol:=42]
DT                 # Ok. DT rebound to new shallow copy (when direct)
   b newcol
1: 1     42
2: 2     42
3: 3     42

DT<-unserialize(serialize(data.table(b = 1:3),NULL))
foo(DT)
   b a
1: 1 1
2: 2 1
3: 3 1
DT                 # but not ok when via function foo()
   b
1: 1
2: 2
3: 3




DT<-unserialize(serialize(data.table(b = 1:3),NULL))
alloc.col(DT)      # alloc.col needed first
   b
1: 1
2: 2
3: 3
foo(DT)
   b a
1: 1 1
2: 2 1
3: 3 1
DT                 # now it's ok
   b a
1: 1 1
2: 2 1
3: 3 1


或者,不要将DT传递给函数,只需直接引用它即可。像数据库一样使用data.table.GlobalEnv中的一些固定名称表。

DT <- unserialize(serialize(data.table(b = 1:5),NULL))
foo <- function() {
   DT[, newcol := 7]
}
foo()
   b newcol
1: 1      7
2: 2      7
3: 3      7
4: 4      7
5: 5      7
DT              # Unserialized data.table now over-allocated and updated ok.
   b newcol
1: 1      7
2: 2      7
3: 3      7
4: 4      7
5: 5      7

关于r - 通过引用分配到加载的包装数据集中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15195220/

相关文章:

r - is.null 不适用于 R 中的 null data.table [可能的错误]?

r - 将大型 2d 矩阵快速融化为 3 列 data.table

r - 如何在一个 data.table 调用中对行进行子集化和排序?

r - mlr:为什么使用并行化时超参数调优的再现性会失败?

r - R 中不同形状的词云

r - 在 R 中运行 kernlab 包的 ksvm 时出现此错误意味着什么

R数据表: compare row value to group values,有条件

r - 如何并行运行多个独立且不相关的函数而无需修改更大的代码?

r - 在 Rstudio 上浏览 R 代码的高效递归方式?

r - 重命名 data.table 的问题