ggplot2的图层附加运算符

问题描述 投票:1回答:1

我爱ggplot2,但我不想每次添加图层时都不要写myplot <- myplot +。例如,

# Load library
library(ggplot2)

# Create plot
myplot <- ggplot(iris) 
myplot <- myplot + geom_point(aes(Sepal.Length, Sepal.Width))
myplot <- myplot + ggtitle("This is a plot")
myplot <- myplot + theme_dark()
myplot

“”

所以,我想在C(+=)中创建类似于加法复合赋值运算符的东西。

# Operator for appending layer
`%+=%` <- function(g, l){
  eval.parent(substitute(g <- g + l))
}

# Test appending function
myplot2 <- ggplot(iris) 
myplot2 %+=% geom_point(aes(Sepal.Length, Sepal.Width))
myplot2 %+=% ggtitle("This is a plot")
myplot2 %+=% theme_dark()
myplot2

<< img src =“ https://image.soinside.com/eyJ1cmwiOiAiaHR0cHM6Ly9pLmltZ3VyLmNvbS9NR2NwREw5LnBuZyJ9” alt =“”>

reprex package(v0.3.0)在2019-12-20创建

如您所见,它给出的结果与正则语法相同。这种方法是根据给定here的解决方案改编为另一个问题的,并附有警告词;但是,我不清楚这为什么会带来问题。

我的问题:像上面那样定义运算符的潜在有害或意外副作用是什么?有没有更好的方法来达到相同的结果?

r ggplot2 eval
1个回答
0
投票

老实说,唯一的缺点是您的构造函数不如ggplot灵活。ggplot已经有一个重载的运算符+,该函数无法直观地与您的函数一起工作。以这个为例:

gg <- ggplot(iris)
gg %+=% geom_point(aes(Sepal.Length, Sepal.Width)) + theme_dark() #plots similar to your answer
   # only geom_point was added to gg variable
   #in other words the expression above is doing this
gg <- ggplot(iris)
gg <- gg + geom_point(aes(Sepal.Length, Sepal.Width))
gg + theme_dark()

这是Infix函数的结果,这些函数始终从左到右求值。因此,除非您能够捕获表达式的其余部分,否则将函数与ggplot的+

结合使用几乎没有希望

在当前状态下,您一次只能分配一个层,这可能比执行时效率低/整洁

gg <- gg + geom_point(aes(Sepal.Length,Sepal.Width)) +
    ggtitle("This is a plot") +
    theme_dark()

它本身也无法使用,但是如果您这样重新编码:

`%+=%` <- function(g, l) {
  UseMethod("%+=%")
}

`%+=%.gg` <- function(g, l){
  gg.name <- deparse(substitute(g))
  gg.name <- strsplit(gg.name, split = "%+=%", fixed= T)[[1]][1]
  gg.name <- gsub(pattern = " ", replacement = "", x = gg.name)
  gg <- g +l
  assign(x = gg.name, value = gg, envir = parent.frame())
}

gg <- ggplot(iris)
gg %+=% geom_point(aes(Sepal.Length, Sepal.Width)) %+=% theme_dark() #will now save left to right

我真的只是挑剔,但是如果您的目的是一次添加一个图层来使用它,那么您的原始功能似乎可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.