ParseException : dev.copy(...) [WinForm]

Jun 13, 2013 at 8:07 PM
Edited Jun 13, 2013 at 8:11 PM
Hello,

First off. I am really excited about this package! I love R and want to make it more accessible to the users at my office. Thank you to the developer and community for pushing this worthy project forward.

But...

I am having a beast of time saving the output of commands to a file. I have looked around and seen that others have had similar issues getting R to output to files. Does anyone have a solid working method of outputting graphs to png, pdf, emf, etc?

As for my code, it throws an exception on this line...
.EagerEvaluate("dev.copy(png, 'C:/Users/me/Documents/r.png')")
... with the error...
An unhandled exception of type 'RDotNet.ParseException' occurred in R.NET.dll

Additional Information: Error in the application.
Below is my code in full, but you won't be able to run as it talks to an Access database on my C drive. If I create the output file directly with R console, and run this code everything works. But as soon as I try to save the output from VB.Net I get the ParseException error.
Imports RDotNet
Imports System.IO.StreamReader

Public Class rForm

    Dim rHome As String = System.Environment.GetEnvironmentVariable("R_HOME")
    Dim path As String = System.Environment.GetEnvironmentVariable("Path")


    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        REngine.SetDllDirectory("C:\Program Files\R\R-2.15.2\bin\i386")
        REngine.CreateInstance("RDotNet")
        Dim engine As REngine = REngine.GetInstanceFromID("RDotNet")

        With engine
            .EagerEvaluate("library(RODBC);")
            .EagerEvaluate("library(ggplot2);")
            .EagerEvaluate("library(scales);")
            .EagerEvaluate("library(plyr);")
            .EagerEvaluate("mycon <- RODBC::odbcConnectAccess(access.file='C:/Users/me/Documents/Projects/AdHoc/MyProj.mdb');")
            .EagerEvaluate("myds <- RODBC::sqlFetch(channel=mycon,sqtable = 'tbl_DealType');")
            .EagerEvaluate("RODBC::odbcClose(channel=mycon);")
            .EagerEvaluate("myds$ldate <- as.Date(myds$ldate);")
            .EagerEvaluate("myds$yr <- myds$ldate >= '2013-02-01';")
            .EagerEvaluate("myds$counts <- ave(myds$Rev, myds$Prod, myds$yr, FUN = sum);")
            .EagerEvaluate("myds$Sales.Perc <- myds$Rev/myds$counts;")
            .EagerEvaluate("sumds <- aggregate(myds$Sales.Perc, list(class=myds$Bucket, Yr=myds$yr, Prod=myds$Product), FUN=sum);")
            .EagerEvaluate("p <- ggplot(sumds, aes(x = x, y = class, color = Yr)) + geom_point(size=4.5, shape=19) + scale_colour_manual(values = c('#BCBDDC','#756BB1')) + theme_bw() + theme(panel.grid.major.x = element_line(color = '#756BB1', linetype = 'dashed'), strip.text = element_text(face='bold', size = rel(1.5), color = 'white'), strip.background = element_rect(fill = '#483D8B', size = 1));")
            .EagerEvaluate("p + facet_wrap( ~ Prod, ncol = 2);")
            .EagerEvaluate("dev.copy(png, 'C:/Users/meDocuments/r.png')")
            .EagerEvaluate("dev.off();")
       End With

Dim str As System.IO.StreamReader = New System.IO.StreamReader("C:\Users\me\Documents\r.png")

        Me.PictureBox1.Image = New Bitmap(str.BaseStream)
        str.Close()
        Me.PictureBox1.Invalidate()
Any ideas? Graphs are the whole reason I want to incorporate R in my programs, but it seems to be a real sticking point in cross application integration...
Developer
Jun 14, 2013 at 10:47 AM
Hi,

Thanks for the reproduction information. Thanks to it I get the same behavior, using v1.5 compiled from source. While not having the same data as you of course, I could mock up something close. I do get a ParseException on the same line as you. The root cause is the call to the native R_tryEval that returns a code that an error occured, see below. Unfortunately without recompiling R with Visual C++ in debug mode, I have no further idea why tryEval fails on this. Compiling R with Visual C++ is a vexed issue, no way I can do that. Maybe with a decent visual environment for GDB, but we'd have to reproduce on Linux.

Anyway, it has to be something pretty low-level happening in dev.copy in a context that somehow differs between RGui and run from the CLR via R.NET.

Maybe the coordinator Kosei has an insight.

It would be nice to nail this one; even "just" figuring out a method to further diagnose these ParseException issues would be valuable learning.

Again, thank you for your interest.
IntPtr pointer = Engine.GetFunction<R_tryEval>("R_tryEval")(handle, environment.DangerousGetHandle(), out errorOccurred);
        Dim envPath = Environment.GetEnvironmentVariable("PATH")
        Dim rBinPath = "C:\Program Files\R\R-3.0.0\bin\x64"
        Environment.SetEnvironmentVariable("PATH", envPath + Path.PathSeparator + rBinPath)
        'REngine.SetDllDirectory("C:\Program Files\R\R-3.0.0\bin\x64")
        REngine.CreateInstance("RDotNet")
        Dim engine As REngine = REngine.GetInstanceFromID("RDotNet")
        engine.Initialize()

        With engine
            '.Evaluate("source('f:/tmp/test.R')")
            .Evaluate("library(ggplot2)")
            .Evaluate("library(scales)")
            .Evaluate("library(plyr)")
            .Evaluate("d <- data.frame( x = rnorm(1000), y = rnorm(1000), z = rnorm(1000))")
            .Evaluate("p <- ggplot(d, aes(x = x, y = y, color = z)) + geom_point(size=4.5, shape=19)")
            .Evaluate("p ")
            .Evaluate("dev.copy(png, 'F:/tmp/r.png')")
            .Evaluate("dev.off()")
        End With
library(ggplot2)
library(scales)
library(plyr)
d <- data.frame( x = rnorm(1000), y = rnorm(1000), z = rnorm(1000))
p <- ggplot(d, aes(x = x, y = y, color = z)) + geom_point(size=4.5, shape=19)
p 
dev.copy(png, 'F:/tmp/r.png')
dev.off()
Jun 14, 2013 at 4:04 PM
Edited Jun 14, 2013 at 4:23 PM
Thank you very much for investigating this. There is something else I have noticed that may support your theory on R's GUI output device being handled differently from .Net.

I tried to scale back my attempt and reproduce the sequence suggested by aoldevstat in Issue#7 using the Cairo library to create png. Using his plot instructions and CairoPNG method to control the output device, I was able to generate the png and load into the form as expected.

However, when I tried to swap out his plotting instructions with mine (using ggplot but generating png with CairoPNG method) it created a blank png file. No errors reported, and the png is loaded into the form, just no content. When using the CairoPNG method from R console to output a ggplot it creates the file with content as expected.

I wonder if anyone has had success outputting graphs with the more advanced packages (ggplot, gobi, lattice)...


Thanks again for your reply.
Developer
Feb 23, 2014 at 7:03 AM
Finally could have a closer look now that retrieval of R native error messages have been improved.
See https://rdotnet.codeplex.com/workitem/41 for a workaround; I don't think this is trivial to copy graphics from one device to another from R.NET