Including a ggplot call with a conditional geom in a function

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Including a ggplot call with a conditional geom in a function

phil-3
How can I write an R function that contains a call to ggplot within it,
with one of the ggplot geom statements being conditional? In my reprex,
I want the plot to contain a horizontal zero line if the y values are
both positive and negative, and to exclude the horizontal line if all of
the y values are of the same sign. I tried a simple if statement, but it
does not work. Suggestions appreciated. Philip

library(rlang)
library(tidyverse)

a <- c(1:8)
b <- c(23,34,45,43,32,45,68,78)
c <- c(0.34,0.56,0.97,0.33,-0.23,-0.36,-0.11,0.17)
df <- data.frame(a,b,c)

posNeg <- function(x) {
   ifelse(sum(x>0)>0 & sum(x>0)<length(x), y <- TRUE,y <- FALSE)
}
plotLineFunc <- function(MYdf,MYx,MYy) {
     ggplot(MYdf,aes(x={{MYx}},y={{MYy}}))+
     #if(posNeg({{MYy}})) geom_hline(yintercept=0,size=0.2)+   # This
does not work
     geom_line(colour="black",size=0.5)
}
(plot1 <- plotLineFunc(df,a,b))
(plot2 <- plotLineFunc(df,a,c))

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Including a ggplot call with a conditional geom in a function

R help mailing list-2
This may not be the right place to ask about ggplot which is part of
packages but are you aware how ggplot works additively?

You can say something like:

P <- ggplot(...) ... + ...

Then later say:

P <- p + geom_...()

And so on.

So if you set al the layers you want first into a variable like p, then in
an if statement you selectively add in one or another layer and finally add
in all remaining layers before printing it, would that simply meet your
need?

Realistically, ggplot creates a data structure and the PLUS of other layers
updates or expands that structure but nothing happens till you print it and
it evaluates the data structure.

-----Original Message-----
From: R-help <[hidden email]> On Behalf Of [hidden email]
Sent: Wednesday, March 24, 2021 10:24 PM
To: [hidden email]
Subject: [R] Including a ggplot call with a conditional geom in a function

How can I write an R function that contains a call to ggplot within it, with
one of the ggplot geom statements being conditional? In my reprex, I want
the plot to contain a horizontal zero line if the y values are both positive
and negative, and to exclude the horizontal line if all of the y values are
of the same sign. I tried a simple if statement, but it does not work.
Suggestions appreciated. Philip

library(rlang)
library(tidyverse)

a <- c(1:8)
b <- c(23,34,45,43,32,45,68,78)
c <- c(0.34,0.56,0.97,0.33,-0.23,-0.36,-0.11,0.17)
df <- data.frame(a,b,c)

posNeg <- function(x) {
   ifelse(sum(x>0)>0 & sum(x>0)<length(x), y <- TRUE,y <- FALSE) }
plotLineFunc <- function(MYdf,MYx,MYy) {
     ggplot(MYdf,aes(x={{MYx}},y={{MYy}}))+
     #if(posNeg({{MYy}})) geom_hline(yintercept=0,size=0.2)+   # This
does not work
     geom_line(colour="black",size=0.5)
}
(plot1 <- plotLineFunc(df,a,b))
(plot2 <- plotLineFunc(df,a,c))

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Including a ggplot call with a conditional geom in a function

Rui Barradas
In reply to this post by phil-3
Hello,

In the following code, the fixed parts of the plot are drawn first,
assigning the plot to p. Then geom_hline is conditionally added to p and
the result returned to caller.
This may be a problem if the conditional geom needs to be in a specified
order in the plot. Function plotLineFunc2 adds everything in the order
of the question and is probably a better way of solving the problem.

I have also rewritten posNeg() without ifelse.

posNeg <- function(x) sum(x>0)>0 & sum(x>0)<length(x)

plotLineFunc <- function(MYdf,MYx,MYy) {
   p <- ggplot(MYdf,aes(x={{MYx}},y={{MYy}}))+
     geom_line(colour="black",size=0.5)
   if(posNeg({{MYy}}))
     p + geom_hline(yintercept=0,size=0.2)
   else p
}

plotLineFunc2 <- function(MYdf,MYx,MYy) {
   p <- ggplot(MYdf,aes(x={{MYx}},y={{MYy}}))
   p <- if(posNeg({{MYy}}))
     p + geom_hline(yintercept=0,size=0.2)
   else p
   p + geom_line(colour="black",size=0.5)
}


(plot1 <- plotLineFunc(df,a,b))
(plot2 <- plotLineFunc(df,a,c))


Hope this helps,

Rui Barradas

Às 02:24 de 25/03/21, [hidden email] escreveu:

> How can I write an R function that contains a call to ggplot within it,
> with one of the ggplot geom statements being conditional? In my reprex,
> I want the plot to contain a horizontal zero line if the y values are
> both positive and negative, and to exclude the horizontal line if all of
> the y values are of the same sign. I tried a simple if statement, but it
> does not work. Suggestions appreciated. Philip
>
> library(rlang)
> library(tidyverse)
>
> a <- c(1:8)
> b <- c(23,34,45,43,32,45,68,78)
> c <- c(0.34,0.56,0.97,0.33,-0.23,-0.36,-0.11,0.17)
> df <- data.frame(a,b,c)
>
> posNeg <- function(x) {
>    ifelse(sum(x>0)>0 & sum(x>0)<length(x), y <- TRUE,y <- FALSE)
> }
> plotLineFunc <- function(MYdf,MYx,MYy) {
>      ggplot(MYdf,aes(x={{MYx}},y={{MYy}}))+
>      #if(posNeg({{MYy}})) geom_hline(yintercept=0,size=0.2)+   # This
> does not work
>      geom_line(colour="black",size=0.5)
> }
> (plot1 <- plotLineFunc(df,a,b))
> (plot2 <- plotLineFunc(df,a,c))
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.