ggplot2在某功能中不起作用,但在外部它起作用

时间:2019-09-27 09:51:46

标签: r ggplot2

我尝试运行ggplot2,但在以下功能foo()中不起作用。为什么?

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()
  }

}

我不明白为什么foo(T)不起作用,但是foo(F)起作用。

请注意,foo(T)运行以下代码,并且在函数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()

编辑@Ronak Shah的答案

如果我们连续使用if语句,则它将丢失对象,如下所示。

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

编辑@Jules Stuifbergen的答案

使用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()

  }

}

2 个答案:

答案 0 :(得分:2)

除非您明确提到return,否则函数将返回该函数最后一行中存在的对象。在您的函数中,您有两个if条件。当aaaTRUE时,它将进入if函数内部,然后检查下一条语句if (aaa==FALSE),因此,当以下情况时,原始ggplot对象会丢失aaaTRUE

只需将第二个if替换为else,您的功能就可以工作。另请注意,如果您的条件已经合乎逻辑,则无需检查if(aaa==TRUE),只有if (aaa)可以工作。

因此将功能更改为

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()  
  }
}

答案 1 :(得分:2)

我无法评论,所以有一个答案:

如前所述,一个函数返回最后一行的内容,所以最后一行仅在FALSE条件下才是绘图。

因此:在两个循环中的ggplot调用周围使用return(),它可以工作。

如果您使用print(),则该函数将始终打印图,并返回意外结果:

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

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