【问题标题】:避免 eval-parse 或 do.call
【发布时间】:2022-01-21 15:41:09
【问题描述】:

我正在尝试根据给定的一些字符串从ggplot2 中选择一个主题。出于演示目的,请考虑以下代码:

library(dplyr); library(ggplot2)
mtcars %>% 
  ggplot(aes(mpg, wt))+
  geom_point() -> p
all_ggplot2_funs <- getNamespaceExports("ggplot2")
p +
eval(parse(text=paste0(all_ggplot2_funs[grep("theme_", all_ggplot2_funs)][15],
                       "()")))

这很好用,可以让我使用theme_minimal。但是,从安全的角度来看,正如在不同语言的 eval-parse 场景的过去线程中所强调的那样,我想避免这种情况。

我可能可以使用do.call,但正在查看类似于python() 的东西,我可以在其中调用基于字符串的函数,例如

methods = {pi: math.pi, sum: math.sum}
methods["pi"]()

什么是 R base 方法来实现这一点?

【问题讨论】:

  • 您可以使用 getFunction("theme_minimal", where = "package:ggplot2") 将 akruns 解决方案直接应用于命名空间,而不是使用导出的函数创建字符向量
  • 感谢@tjebo,这比选择theme_minimal 稍微复杂一些。我想获得所有这些主题,将它们存储在某个地方(闪亮的东西),然后我可以稍后根据提供的字符串进行 grep,但解决方案确实非常 useful

标签: r ggplot2


【解决方案1】:

我们可能会使用getFunction

library(ggplot2)
p1 <- p + 
   getFunction(all_ggplot2_funs[grep("theme_", all_ggplot2_funs)][15])()

-检查

> p2 <- p + theme_minimal()
> all.equal(p1, p2)
[1] TRUE

【讨论】:

  • 只是好奇和学习效果。这在什么情况下会有用?
  • @TarJae。你也可以使用get,但getFunction 我想更具体的功能
【解决方案2】:

我认为您不需要单独提取函数列表,因为它已经可以在函数列表中访问。而且,对于ggplot2-universe 未来添加的功能,按名称而不是按列表中的位置调用函数似乎更稳定,所以我主张:

choice <- "minimal"
p+ match.fun( paste0("theme_", choice) )()

【讨论】:

  • 谢谢,抱歉,这只是一个例子。对于真实情况,我确实使用了基于 grep 的名称。这也是一个优雅的解决方案。
猜你喜欢
  • 2012-11-18
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多