1

我正在对大型数据集(约 10,000 个数据点分为约 10 条曲线)进行一些探索性分析。我正在使用manipulateRStudio 中的包来更改 x 轴限制。问题是使用新参数重新绘制绘图可能需要 5 秒以上的时间。我希望有一种方法可以加快速度。我正在使用该lattice软件包。这是一个简化的例子......

set.seed(100)
x = rep(1:5,20)
y = rnorm(100)
groups = gl(20,5)
p = xyplot(y~x,groups=groups,type="l",
           auto.key=list(space="right",lines=TRUE,
                         points=TRUE,rectangles=TRUE) )

Rprof(interval=0.001)
print(p)
Rprof(NULL)
head( summaryRprof()$by.total )
                  total.time total.pct self.time self.pct
"print"                0.239    100.00     0.000     0.00
"printFunction"        0.239    100.00     0.000     0.00
"print.trellis"        0.239    100.00     0.000     0.00
"do.call"              0.126     52.72     0.001     0.42
"draw.key"             0.098     41.00     0.001     0.42
"evaluate.legend"      0.098     41.00     0.000     0.00

请注意,这draw.key需要 41% 的运行时间(是的,选择这个多余的传说是为了强调我的观点)。为了我的目的,我的传奇永远不会改变,但情节会。那么有没有办法从一个情节中保存图例、密钥或任何内容并一遍又一遍地重用它(也许重用Grob来自 的对象lattice::draw.key)?我已经研究了一些代码,lattice:::plot.trellis看起来应该有办法做到这一点。但是,这样做似乎需要大量的新代码。有简单的解决方案吗?或者,是否有任何其他以速度着称的绘图功能或软件包?我当然可以将平滑曲线拟合到我的数据中以“压缩/下采样”它,但我宁愿不这样做。

4

2 回答 2

1

我有时发现打印到文件比打印到屏幕上然后打开文件要快。

这不是你要找的,但如果它足够快,它会简单得多......

于 2013-10-30T01:49:11.490 回答
1

简而言之,是的,有一些方法可以根据预先计算的网格对象或其他参数加快点阵图的打印速度。但是,据我所知,没有简单的解决方案。为此,我需要深入研究点阵绘图函数的来源,plot.trellis以确定可以优化速度的点。继续问题中的示例...

# Save the legend from the last plot
plot.grob = trellis.last.object()
legend.grob = lattice:::evaluate.legend( plot.grob$legend )

# Modify the default plotting function
f = lattice:::plot.trellis
b = body(f)
fun.line = which(!is.na(str_match(as.character(b),"evaluate.legend")))
new.line = substitute(legend <- if(is.null(legend.object)) 
                        evaluate.legend(x$legend) else legend.object)
body(f)[[fun.line]] = new.line
args = formals(f)
formals(f) = do.call(alist, c( args[2:length(args)-1], alist(legend.object=NULL,...=)) )

# Note that evaluate.legend is no longer taking up any time because it's not called
Rprof()
f(plot.grob,legend.object=legend.grob)
Rprof(NULL)
head(summaryRprof()$by.total)

# the modified function is faster
times = data.frame( modified.fun=NA, standard.fun=NA )
for( i in 1:100 ) {
  t1 = profr( f(plot.grob,legend.object=legend.grob), interval=0.001 )[1,"time"]
  t2 = profr( plot(plot.grob), interval=0.001 )[1,"time"]
  times = rbind( times, c( t1, t2 ) )
}
colMeans(na.omit(times))
modified.fun standard.fun 
     0.11435      0.19757

我修改后的函数花费的时间减少了大约 40%,这是有道理的,因为在问题中给出的示例中,evaluate.legend调用花费了大约 40% 的运行时间。plot.trellis该功能中还有许多其他地方plot.trellis可以优化速度。如果要继续下去,他们最终可以将函数简化为最基本的功能,以便grid调用包中唯一的函数。这本质上是重写一个全新的plot.trellis功能,降低了灵活性但提高了速度。然而,这不是我想要的。

在旁注中,我注意到在我的屏幕上实际绘制绘图所需的时间比分析代码报告的运行时间要长。我用秒表计时,在报告代码运行完成后,绘图显示的时间要长不到 1 秒。我尝试使用其他同样依赖grid并发现类似结果的绘图包。因此,无论绘图功能优化得多么好,grid当我的时间降至 1 秒或更短时,我决定无论是基础 R 还是我的硬件最终都会成为限制因素。这个新问题有解决方案,但这是另一个话题......

于 2013-11-04T03:45:36.193 回答