Say I have a table that has stored some things that happened during an R session:
steplist.table <- structure(list(auto.sum = structure(list(step1 = "summary1",
step2 = "summary2"), .Names = c("step1", "step2")), code = structure(list(
step1 = "x(5)", step2 = print("boo")), .Names = c("step1",
"step2")), enabled = structure(list(step1 = TRUE, step2 = TRUE), .Names = c("step1",
"step2"))), .Names = c("auto.sum", "code", "enabled"), row.names = c("step1",
"step2"), class = "data.frame")
or:
auto.sum code enabled
step1 summary1 x(5) TRUE
step2 summary2 print("boo") TRUE
I'd like to place this in a gtable()
and then hide the code
column from view. The code
column needs to come along, because the user will make some changes to the table within the GUI. It looks like gtable()
evaluates the expressions in the code
column, though, and it definitely doesn't appear properly.
example:
library(gWidgets)
mygw <- gwindow()
gtable(steplist.table, container = mygw, filter.column = "code")
The above code will actually print "boo", (while leaving the string "x(5)"
alone), which is not good.
I was planning on inserting the code using the convenient quote()
as was done above with print(boo)
, but if there's a workaround that involves creating sanitized R code strings that can also be parsed by the interpreter, I'm happy to use that instead. I haven't been able to find it yet.
Here is a fairly robust solution that at least addresses placing the code
within a string, insulating it from possible evaluation during the process of assignment:
new.step <- list(summary = step.summary,
enabled = FALSE,
code = paste(deparse(
bquote(do.call(.(func.name), .(step.args))),
# ensure we get knittable code
control = c("showAttributes" = NULL)),
collapse = "\n")
)
There are a few things going on here:
.()
when inside bquote()
.deparse()
will convert the resulting call
object to a string, but it usually includes a bunch of metadata-like stuff, wrapping the elements inside structure()
calls. This confuses knitr
, so we drop it with "showAttributes" = NULL
, which strips it from deparse
's opts list for this call.parse
will interpret as character vector delimiters, so we collapse the result with newlines, which was the apparent original intent of the formatting of the resulting deparse()
call.As a kludge, the code
element is placed last in the list, ensuring that when converted to a named column in the gtable
dataframe, it will be rightmost (and out of view in my use case).
I'm going to go soak my head in an ice bucket now and try to forget about metaprogramming.