在data.table列表列中保存图表

14

当我运行时...

library(data.table)
DT = CJ(id = 1, id2 = 1:3)[, .(
    d = as.IDate("2017-01-01")+1:10, v = id*10 + id2*1:10
), by=.(id, id2)]

plotDT = DT[, {
    par(mfrow = c(uniqueN(id2), 1), mar = c(2,2,.5,2))
    .SD[,{ 
        plot(d, v, type="l")
    }, by=id2]
    .(p = .(recordPlot()))
}, by=id]

x11()
plotDT[id == 1L, replayPlot(p[[1]])]

DT[...]的情节是正确的:

而回放却是错误的:

在记录的图中,xy的最终值被神奇地应用于所有三个图表,这可能是由于data.table处理在by=组中定义的列指针的方式所致。

尽管如此,我并不确定自己理解了发生了什么,因为我可以对示例进行表面上的更改,将v=id2*1:10改为v=id*10+id2*1:10然后问题就消失了。

我想知道:(i)为什么会出现这种情况, (ii)有什么简单的调整我可以做来避免它?


3
毫不意外,一种解决方法是通过使用v + 0代替v,确保变量按值传递。在我听到更好的方法之前,我会这样做。 - Frank
1
当我运行这段代码时,普通的DT图和记录图(都是错误的)给出了相同的结果。然而,当我切换到 v = id2*1:10 时,两者确实都给出了正确的结果。 - takje
1
我使用R版本3.3.2进行了测试。数据表版本相同。 - takje
1
调整绘图窗口的大小会得到与“replayPlot”相同的结果。 - user3226167
为了以后参考:目前来看,with(copy(.SD), {yada j}) 是一个足够好的解决方法。参考链接:http://stackoverflow.com/questions/43536583/data-table-not-returning-correct-plots?noredirect=1&lq=1#comment74148898_43548292 - Frank
显示剩余8条评论
1个回答

2
一种有效的技巧是将 j 写成
with(copy(.SD), {yada yada})

或类似的方式,确保引用指向每个组的.SD的副本,而不会混淆。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接