将ggplot调用存储在data.frame中(或替代方法),然后对其进行评估

时间:2019-04-01 14:03:44

标签: r ggplot2

我想将ggplot个调用存储在data.frame(或替代方法)中,并在以后进行评估。

一个例子:

define <- function(df, call) {
  df[nrow(df) + 1, ] <- call
  df
} 

plot <- function(df, index) {
  eval(parse(text = df$plots[index]))
}

df <- data.frame(plots = character(0), stringsAsFactors = FALSE)

df <- define(df, "ggplot() + geom_segment(aes(x = 1, y = 1, xend = 2, yend = 2))")
df <- define(df, "ggplot() + geom_segment(aes(x = 1, y = 2, xend = 2, yend = 1))")

plot(df, 1)
plot(df, 2)

这种作品和情节:

enter image description here enter image description here

但是有一些问题

  1. 我想定义没有'“'符号的呼叫。例如define(df, ggplot() + geom_..)
  2. 我宁愿将调用存储为call对象。

我该如何实现?

2 个答案:

答案 0 :(得分:4)

在这种情况下,我将使用一个列表。 data.frame在存储未评估的内容时会有些棘手(因为它们包含的信息比调用还多)。列表更加通用(在这种情况下更易于使用):

#saves the unevaluated call
define <- function(mylist, call) {
  mylist[[length(mylist) + 1]] <- substitute(call)
  mylist
} 

#evaluates the call
ploteval <- function(mylist, index) {
  eval(mylist[[index]])
}

mylist <- list()

mylist <- define(mylist, ggplot() + geom_segment(aes(x = 1, y = 1, xend = 2, yend = 2)))
mylist <- define(mylist, ggplot() + geom_segment(aes(x = 1, y = 2, xend = 2, yend = 1)))


ploteval(mylist, 1)
ploteval(mylist, 2)

这将起作用。

enter image description here

enter image description here

作为一个简短的解释,替代将存储未评估的调用,然后将使用ploteval对其进行评估。覆盖plot也不是一个好主意,因此我给它起了一个新名称ploteval

答案 1 :(得分:2)

我们还可以将表达式捕获为表达式(enexpr)并存储为字符串

define <- function(df, call) {

    df[nrow(df) + 1, ] <- rlang::as_label(rlang::enexpr(call))
   df

}

plot <- function(df, index) {
  eval(parse(text = df[["plots"]][index]))
}


df <- data.frame(plots = character(0), stringsAsFactors = FALSE)
df <- define(df, ggplot() + geom_segment(aes(x = 1, y = 1, xend = 2, yend = 2)))
df <- define(df, ggplot() + geom_segment(aes(x = 1, y = 2, xend = 2, yend = 1)))

plot(df, 1)
plot(df, 2)