函数返回data.table时是否复制?

ial*_*alm 6 r data.table

我正在更新一组以前只接受data.frame对象来处理data.table参数的函数.

我决定使用R的方法调度来实现该函数,以便使用data.frames 的旧代码仍然可以使用更新的函数.在我的一个函数中,我接受一个data.frame输入,修改它,然后返回修改后的data.frame.我也创建了一个data.table实现.例如:

# The functions
foo <- function(d) {
  UseMethod("foo")
}

foo.data.frame <- function(d) {
  <Do Something>
  return(d)
}

foo.data.table <- function(d) {
  <Do Something>
  return(d)
}
Run Code Online (Sandbox Code Playgroud)

我知道这data.table可以通过在不复制的情况下进行更改来实现foo.data.table,并且在实现这一目 但是,我data.table在函数末尾返回对象,因为我希望我的旧脚本能够处理新data.table对象.这会复制data.table吗?我怎么检查?根据文档,必须非常明确地创建一个a的副本data.table,但在这种情况下我不确定.

当我不需要时,我想要返回一些东西data.tables:

我的旧脚本看起来像这样

someData <- read.table(...)
...
someData <- foo(someData)
Run Code Online (Sandbox Code Playgroud)

我希望脚本能够data.table通过更改数据摄取行来运行s.换句话说,我希望脚本只需更改someData <- read.table(...)即可工作someData <- fread(...).

ial*_*alm 5

感谢Arun在评论中的回答.我将在他的评论中使用他的例子来回答这个问题.

可以通过使用该tracemem功能来跟踪R中的对象来检查是否正在制作副本.从该功能的帮助文件中?tracemem,描述说:

此函数标记一个对象,以便在内部代码复制对象时打印消息.这是R中难以预测的内存使用的主要原因.

例如:

# Using a data.frame
df <- data.frame(x=1:5, y=6:10)
tracemem(df)
## [1] "<0x32618220>"
df$y[2L] <- 11L
## tracemem[0x32618220 -> 0x32661a98]: 
## tracemem[0x32661a98 -> 0x32661b08]: $<-.data.frame $<- 
## tracemem[0x32661b08 -> 0x32661268]: $<-.data.frame $<- 
df
##   x  y
## 1 1  6
## 2 2 11
## 3 3  8
## 4 4  9
## 5 5 10

# Using a data.table
dt <- data.table(x=1:5, y=6:10)
tracemem(dt)
## [1] "<0x5fdab40>"
set(dt, i=2L, j=2L, value=11L) # No memory output!
address(dt) # Verify the address in memory is the same
## [1] "0x5fdab40"
dt
##    x  y
## 1: 1  6
## 2: 2 11
## 3: 3  8
## 4: 4  9
## 5: 5 10
Run Code Online (Sandbox Code Playgroud)

看来,data.frame当更改一个元素时,对象被复制两次data.frame,而data.table在不进行复制的情况下进行了修改!

从我的问题来看,我可以跟踪它data.tabledata.frame对象,d然后再将其传递给函数foo,以检查是否有任何副本.

  • 优秀!你也可以检查`地址(dt $ x)`. (2认同)