我是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
以达到预期的结果)
答案 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