0

I try to run ggplot2 but it does not work in the following function foo(). Why?

foo <- function(aaa=TRUE) {

  df<-data.frame(x=c(10,100,1000,10,100,1000),
                 y=c(1100,220000,33000000,1300,240000,36000000),
                 group=c("1","1","1","2","2","2")
  )



if (aaa==TRUE) {
  ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
    ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
    ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
    ggplot2::scale_y_log10()+
    ggplot2::scale_x_log10()
}

  if (aaa==FALSE) {
    ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
      ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
      ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
      ggplot2::scale_y_log10()
      # ggplot2::scale_x_log10()
  }

}

I cannot understand why foo(T) does not work but foo(F) work.

Note that foo(T) runs the following codes, and it works outside the function foo.

df<-data.frame(x=c(10,100,1000,10,100,1000),
               y=c(1100,220000,33000000,1300,240000,36000000),
               group=c("1","1","1","2","2","2")
)

ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
  ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
  ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
  ggplot2::scale_y_log10()+
  ggplot2::scale_x_log10()

Edit for the answer of @Ronak Shah

if we use if statement successively, then it lost the object as the following code.

df<-data.frame(x=c(10,100,1000,10,100,1000),
               y=c(1100,220000,33000000,1300,240000,36000000),
               group=c("1","1","1","2","2","2")
)

aaa<-TRUE

if (aaa==TRUE) {
  ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
    ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
    ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
    ggplot2::scale_y_log10()+
    ggplot2::scale_x_log10()
}

.Last.value

if (aaa==FALSE) {
  ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
    ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
    ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
    ggplot2::scale_y_log10()
  # ggplot2::scale_x_log10()
}

.Last.value

Edit for the answer of @Jules Stuifbergen

Using return()

# General print of log scale

foo <- function(aaa=TRUE) {

  df<-data.frame(x=c(10,100,1000,10,100,1000),
                 y=c(1100,220000,33000000,1300,240000,36000000),
                 group=c("1","1","1","2","2","2")
  )



if (aaa==TRUE) {
 return( ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
    ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
    ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
    ggplot2::scale_y_log10()+
    ggplot2::scale_x_log10()
 )

}

  if (aaa==FALSE) {
    ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
      ggplot2::geom_line(position = position_dodge(0.2)) +           # Dodge lines by 0.2
      ggplot2::geom_point(position = position_dodge(0.2), size = 4)+  # Dodge points by 0.2
      ggplot2::scale_y_log10()
      # ggplot2::scale_x_log10()

  }

}
Camford Oxbridge
  • 834
  • 8
  • 21

2 Answers2

2

A function returns the object which is present in the last line of the function unless you have mentioned return explicitly. In your function you have two if condition. When aaa is TRUE it will go inside the if function and then check for if (aaa==FALSE) which is the next statement hence, the original ggplot object is lost when aaa is TRUE

Your function would work simply by replacing second if with only else. Also note that if your condition is already logical you don't need to check if(aaa==TRUE), only if (aaa) would work.

So change the function to

foo <- function(aaa=TRUE) {

  df<-data.frame(x=c(10,100,1000,10,100,1000),
             y=c(1100,220000,33000000,1300,240000,36000000),
             group=c("1","1","1","2","2","2"))

  if (aaa) {
    ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
      ggplot2::geom_line(position = position_dodge(0.2)) +         
      ggplot2::geom_point(position = position_dodge(0.2), size = 4)+
      ggplot2::scale_y_log10()+
      ggplot2::scale_x_log10()
  }
  else {
     ggplot2::ggplot(df, aes(x = x, y = y, shape = group)) +
      ggplot2::geom_line(position = position_dodge(0.2)) +        
      ggplot2::geom_point(position = position_dodge(0.2), size = 4) +
      ggplot2::scale_y_log10()  
  }
}
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
2

I cannot comment, so here's an answer:

As said, a function returns what's on the last line, so the last line is a plot, only in the FALSE condition.

So: Use return() around the ggplot calls in both loops, and it works.

If you use print() then the function will always print the plot, and will return unexpected results:

p <- foo(FALSE)     # prints the plot
p + theme_minimal() # works

p <- foo(TRUE)     # prints the plot
p + theme_minmal() # doesnt work