Jon*_*nas 7 r rstudio data.table
我想生成一个分开的图表.在图的上半部分是组的值a,在较低的一个组中b应该使用组的值.我正在使用data.table()这个.这是我用来生成示例并设置图形输出的代码:
library(data.table)
set.seed(23)
Example <- data.table('group' = rep(c('a', 'b'), each = 5), 'value' = runif(10))
layout(1:2)
par('mai' = rep(.5, 4))
Run Code Online (Sandbox Code Playgroud)
在通常的r控制台中运行以下行时,正确的值用于绘图.在Rstudio中运行相同的代码时,第二组的值将用于两个图表:
Example[, plot(value, ylim = c(0, 1)), by = group] # Example 1
Example[, .SD[plot(value, ylim = c(0, 1))], by = group] # Example 2
Run Code Online (Sandbox Code Playgroud)
在.SD[]示例2 的子集data.table 中添加逗号时,也会在Rstudio中生成正确的输出:
Example[, .SD[, plot(value, ylim = c(0, 1))], by = group] # Example 3
Run Code Online (Sandbox Code Playgroud)
使用时,barplot()而不是plot()Rstudio使用正确的值:
Example[, barplot(value, ylim = c(0, 1)), by = group] # Example 4
Run Code Online (Sandbox Code Playgroud)
我忽略了什么或这是一个错误吗?
系统:Windows 7,Rstudio Desktop v0.98.1091,R 3.1.2,data.table 1.9.4
很好的捕获(已经+1了)!在我的例子中,例3也没有产生正确的图(OS X 10.10.1,R 3.1.2,Rstudio 0.98.1091).
R控制台/ GUI和Rstudio之间的唯一区别是绘图设备.RStudio似乎使用本机图形设备RstudioGD,R控制台/ GUI使用Quartz.
通过调试,graphics:::plot.default我能够将问题缩小到函数范围plot.xy().此函数调用不同的图形设备(如上所示).
通过启动,例如,Quartz通过调用该函数quartz(),然后运行您的代码工作正常!
FWIW这个问题也可以使用dplyr():
require(dplyr)
df = as.data.frame(Example)
my_fun = function(x) {plot(x, ylim=c(0,1)); 1L }
df %>% group_by(group) %>% summarise(my_fun(value))
Run Code Online (Sandbox Code Playgroud)
会导致同样错误的情节.
这很可能是由于在data.table中处理子组的方式(我认为dplyr应该以与data.table相同的方式执行),您可以通过以下方式看到:
Example[, print(sapply(.SD, address)), by=group]
# value
# "0x105bbf5b8"
# value
# "0x105bbf5b8"
# Empty data.table (0 rows) of 1 col: group
Run Code Online (Sandbox Code Playgroud)
data.table.SD为每个子组分配最大的组并在内部重用此内存,以避免重复的内存alloc/dealloc - 以提高效率.不确定(在这里黑暗中拍摄),但似乎RstudioGD没有释放与子组链接的指针,并且当子组中的数据得到更新时,图也会更新.您可以通过以下方式验证这一点
# on RstudioGD
debug(graphics:::plot.default)
set.seed(23)
Example <- data.table('group' = rep(c('a', 'b'), each = 5), 'value' = runif(10))
layout(1:2)
par('mai' = rep(.5, 4))
Example[, plot(value, ylim = c(0, 1)), by = group] # Example 1
undebug(graphics:::plot.default)
Run Code Online (Sandbox Code Playgroud)
继续按Enter键,你会看到第一个绘图正确绘制..当添加第二个绘图时,第一个绘图也会改变.这可能是最近Rv3.1 +变化的结果,浅拷贝的功能是参数而不是深度复制(再次,在这里黑暗中拍摄).
您可以通过显式复制临时解决此问题value:
Example[, plot(copy(value), ylim = c(0, 1)), by = group] # Example 1
Run Code Online (Sandbox Code Playgroud)
将产生正确的情节.