不希望在传递给函数

时间:2017-06-20 19:57:29

标签: r ggplot2 data.table

我是data.table的粉丝,在编写可重复使用的功能时,可满足当前和未来的所有需求。

这是我在解决此问题的过程中遇到的挑战:Best way to plot automatically 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

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

3 个答案:

答案 0 :(得分:1)

尝试:

dt <- copy(.dt)

它应该运作良好。

答案 1 :(得分: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]) 

}

但是,同样重要的是要了解在使用data.table时,应该特别注意不要制作任何副本&#34;它使用常规<-符号,但请改用copy(dt) - 以免损坏原始data.table
这将在此处进一步详细讨论:Understanding exactly when a data.table is a reference to (vs a copy of) another data.table

答案 2 :(得分:0)

只是省略了:=函数似乎成功了。当然,我将ggplot值包装在print(.)中,这是在函数内部工作并想要输出时的标准做法。:

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

> png(); plotYofX(dtDiamonds,1,2); dev.off()
quartz 
     2 
>  dtDiamonds
   carat     cut color
1:  0.21 Premium     E
2:  0.23    Good     E
3:  0.29 Premium     I
4:  0.31    Good     J

enter image description here