不希望在传递给函数时修改原始 data.table

IVI*_*VIM 5 r ggplot2 data.table

我是 的粉丝data.table,因为我喜欢为所有当前和未来的需求编写可重用的函数。

这是我在解决这个问题时遇到的一个挑战: Best way to automatically plot all data.table columns using ggplot2

我们将 data.table 传递给一个函数进行绘图,然后原始的 data.table 被修改,即使我们复制了它来防止这种情况发生。

下面是一个简单的代码来说明:

plotYofX <- function(.dt,x,y) {
  dt <- .dt
  dt[, (c(x,y)) := lapply(.SD, function(x) {as.numeric(x)}), .SDcols = c(x,y)]
  ggplot(dt) + geom_step(aes(x=get(names(dt)[x]), y=get(names(dt)[y]))) + labs(x=names(dt)[x], y=names(dt)[y])
}


> dtDiamonds <- data.table(ggplot2::diamonds[2:5,1:3]); 
> dtDiamonds
   carat     cut color
   <num>   <ord> <ord>
1:  0.21 Premium     E
2:  0.23    Good     E
3:  0.29 Premium     I
4:  0.31    Good     J

> plotYofX(dtDiamonds,1,2); 
> dtDiamonds
    carat   cut color
    <num> <num> <ord>
1:  0.21     4     E
2:  0.23     2     E
3:  0.29     4     I
4:  0.31     2     J
Run Code Online (Sandbox Code Playgroud)

我已经看到很多关于:=在函数内部使用相关的各种问题的帖子,但找不到任何帖子来帮助我解决这个看似非常简单的问题。(当然,我不知道将它转换回什么data.frame以达到预期的结果)

IVI*_*VIM 1

感谢上面的评论/答案:这将是这个特定函数的最简单的解决方案(即根本不需要引入任何额外的.dt变量);

plotYofX <- function(dt,x,y) {
  dt[,  lapply(.SD, function(x) {as.numeric(x)}), .SDcols = c(x,y)]
  ggplot(dt) + geom_step(aes(x=get(names(dt)[x]), y=get(names(dt)[y]))) + labs(x=names(dt)[x], y=names(dt)[y]) 
Run Code Online (Sandbox Code Playgroud)

}

然而,了解这一点也很重要:在使用 时data.table,应特别小心,不要使用常规符号对其进行任何“副本” <-,而是使用copy(dt)它 - 这样才不会损坏原始文件data.table
此处详细讨论了这一点: 准确理解何时 data.table 是对另一个 data.table 的引用(与副本)