简体   繁体   English

使用 if 循环制作用户定义的 ggplot 派生函数并在另一个自定义 function 中调用它们

[英]Making user-defined ggplot derived functions and calling them inside another custom function with if loops

I have two custom functions that produce a bar or jitter graph.我有两个生成条形图或抖动图的自定义函数。 If an object exists, I would like it to produce the bar graph.如果 object 存在,我希望它生成条形图。 If an object doesn't exist, I would like the jitter graph to be produced.如果 object 不存在,我希望生成抖动图。 I think the problem is making the code inside the if loop within a function dynamic so it can be altered to any dataset.我认为问题在于使 function 动态的 if 循环内的代码可以更改为任何数据集。

This is what I have so far, I think this will be an easy fix and I may just be missing formatting/syntax etc... (be kind I am new to writing functions in r).这是我到目前为止所拥有的,我认为这将是一个简单的修复,我可能只是缺少格式/语法等......(请善意,我是在 r 中编写函数的新手)。

data <- iris

#graph 1 function:
make_bar_graph <- function(data, x, y, xlab = NULL, ylab = NULL, 
                             linewidth = 0.5, colour = NULL, fill = NULL, 
                             stat.colour = "black", 
                             bar.position = "dodge", bar.width = 0.8, bar.colour = "black", 
                             point.position = position_jitterdodge(0.7), point.size = 2,
                             errorbar.position = position_dodge(0.8), errorbar.width = 0.3, errorbar.colour = "black",
                             ...) {
  ggplot(data = data, aes(x = {{x}}, y = {{y}}, fill = {{fill}}, colour = {{colour}})) +
    geom_bar(stat="summary", fun = "mean", position = bar.position, width = bar.width, colour = bar.colour, show.legend = FALSE, inherit.aes=TRUE, ...) +
    geom_hline(yintercept=0) +
    labs(x=xlab, y=ylab) +
    geom_point(position = point.position, size = point.size, show.legend = FALSE, ...) +
    scale_fill_manual(values = c("gray95", "gray85", "gray75", "gray65", "gray55", "gray45")) +
    scale_colour_manual(values=c("#FF5695", "#8E8DFF", "#8CB5FF", "#79DBFF", "#42EFD7", "#79EBAC")) +
    theme(axis.title.x = element_blank())
   
}


#graph 1 example:
make_bar_graph(data, Species, Petal.Width, fill = Species, colour = Species)


#graph2 function
make_jitter_graph <- function(data, x, y, xlab = NULL, ylab = NULL, linewidth = 0.5, size.jitter = 2, colour = NULL, fill = NULL, stat.colour = "black", ...) {
  ggplot(data = data, aes(x = {{x}}, y = {{y}}, fill = {{fill}}, colour = {{colour}})) +
    stat_summary(fun = median, show.legend = FALSE, geom="crossbar", linewidth = linewidth, colour = stat.colour, ...) +
    geom_jitter(show.legend = FALSE, width = 0.25, size = size.jitter, ...) +
    labs(x=xlab, y=ylab)
}

#graph 2 example:
make_jitter_graph(data = data, x = Species, y = Petal.Width, colour = Species, fill = Species)



#How can I make either of these two graphs produced in a loop:
make_graphs <- function(data, x, y, xlab = NULL, ylab = NULL, 
                             linewidth = 0.5, colour = NULL, fill = NULL, 
                             stat.colour = "black", 
                             bar.position = "dodge", bar.width = 0.8, bar.colour = "black", 
                             point.position = position_jitterdodge(0.7), point.size = 2, 
                             errorbar.position = position_dodge(0.8), errorbar.width = 0.3, errorbar.colour = "black", size.jitter = 2,
                             ...){
  if(exists("OBJECT")){
    require(ggpubr)
    make_bar_graph(data = data, x=x, y=y, linewidth = linewidth, colour = colour, fill = fill,
                       stat.colour = stat.colour, bar.position=bar.position,  bar.width=bar.width, bar.colour=bar.colour,
                       point.position=point.position, point.size=point.size, errorbar.position = errorbar.position, errorbar.width = errorbar.width, errorbar.colour = errorbar.colour, ...)
  }else{
    make_jitter_graph(data = data, x=x, y=y, linewidth = linewidth, colour = colour, fill = fill, stat.colour = stat.colour, size.jitter=size.jitter, ...)
  }
}

# Run when OBJECT doesn't exist:
make_graphs(data = data, x = Species, y = Petal.Width, colour = Species, fill = Species)

#Get error: Error in stat_summary(fun = median, show.legend = FALSE, geom = "crossbar", : ℹ Error occurred in the 1st layer. Caused by error in `FUN()`: ! object 'Species' not found

# Run when OBJECT exists
OBJECT <- 4
make_graphs(data = data, x = Species, y = Petal.Width, colour = Species, fill = Species)

#Get the error: Error in geom_bar(stat = "summary", fun = "mean", position = bar.position, : ℹ Error occurred in the 1st layer. Caused by error in `FUN()`: ! object 'Species' not found

Thank you!谢谢!

EDIT - two ways to do this:编辑 - 两种方法:

1) Putting calls to ggplot2 inside make_graphs() 1) 在make_graphs()中调用 ggplot2

I think there's probably a way to make the whole process more concise, but could you just eliminate the first two functions entirely and put the ggplot calls inside your make_graphs function?我认为可能有一种方法可以使整个过程更加简洁,但是您可以完全消除前两个函数并将 ggplot 调用放在您的make_graphs function 中吗? Like this像这样

make_graphs <- function(data, x, y, xlab = NULL, ylab = NULL, 
                        linewidth = 0.5, colour = NULL, fill = NULL, 
                        stat.colour = "black", 
                        bar.position = "dodge", bar.width = 0.8, bar.colour = "black", 
                        point.position = position_jitterdodge(0.7), point.size = 2, 
                        errorbar.position = position_dodge(0.8), errorbar.width = 0.3, errorbar.colour = "black", size.jitter = 2,
                        ...){
  if(exists("OBJECT")){
    require(ggpubr)
    ggplot(data = data, aes(x = {{x}}, y = {{y}}, fill = {{fill}}, 
                            colour = {{colour}})) +
      geom_bar(stat="summary", fun = "mean", position = bar.position, 
               width = bar.width, colour = bar.colour, show.legend = FALSE, 
               inherit.aes=TRUE, ...) +
      geom_hline(yintercept=0) +
      labs(x=xlab, y=ylab) +
      geom_point(position = point.position, size = point.size, 
                 show.legend = FALSE, ...) +
      scale_fill_manual(values = c("gray95", "gray85", "gray75", "gray65", 
                                   "gray55", "gray45")) +
      scale_colour_manual(values=c("#FF5695", "#8E8DFF", "#8CB5FF", "#79DBFF", 
                                   "#42EFD7", "#79EBAC")) +
      theme(axis.title.x = element_blank())  }else{
    ggplot(data = data, aes(x = {{x}}, y = {{y}}, fill = {{fill}}, 
                            colour = {{colour}})) +
      stat_summary(fun = median, show.legend = FALSE, geom="crossbar", 
                   linewidth = linewidth, colour = stat.colour, ...) +
      geom_jitter(show.legend = FALSE, width = 0.25, size = size.jitter, ...) +
      labs(x=xlab, y=ylab)  }
}

Then when the object doesn't exist you get this:然后当 object 不存在时,你会得到这个:

rm(OBJECT)
make_graphs(data = data, x = Species, y = Petal.Width, 
            colour = Species, fill = Species)

在此处输入图像描述

And when it does exist you get this:当它确实存在时,你会得到这个:

OBJECT <- 4
make_graphs(data = data, x = Species, y = Petal.Width, 
            colour = Species, fill = Species)

在此处输入图像描述

2) Using aes_string() 2) 使用aes_string()

Here, you'd change the way you set up the ggplot functions, so they get their aes() passed as aes_string() instead, then put actual strings in the make_graphs() call.在这里,您将更改设置 ggplot 函数的方式,以便它们将aes()作为aes_string() ) 传递,然后将实际字符串放入make_graphs()调用中。 The graph functions get defined like this now:图形函数现在定义如下:

make_bar_graph <- function(data, x, y, xlab = NULL, ylab = NULL, 
                           linewidth = 0.5, colour = NULL, fill = NULL, 
                           stat.colour = "black", 
                           bar.position = "dodge", bar.width = 0.8, bar.colour = "black", 
                           point.position = position_jitterdodge(0.7), point.size = 2,
                           errorbar.position = position_dodge(0.8), errorbar.width = 0.3, errorbar.colour = "black",
                           ...) {
  ggplot(data = data, aes_string(x = x, y = y, fill = fill, colour = colour)) +
    geom_bar(stat="summary", fun = "mean", position = bar.position, width = bar.width, colour = bar.colour, show.legend = FALSE, inherit.aes=TRUE, ...) +
    geom_hline(yintercept=0) +
    labs(x=xlab, y=ylab) +
    geom_point(position = point.position, size = point.size, show.legend = FALSE, ...) +
    scale_fill_manual(values = c("gray95", "gray85", "gray75", "gray65", "gray55", "gray45")) +
    scale_colour_manual(values=c("#FF5695", "#8E8DFF", "#8CB5FF", "#79DBFF", "#42EFD7", "#79EBAC")) +
    theme(axis.title.x = element_blank())
  
}

make_jitter_graph <- function(data, x, y, xlab = NULL, ylab = NULL, linewidth = 0.5, 
                              size.jitter = 2, colour = NULL, fill = NULL, 
                              stat.colour = "black", ...) {
  ggplot(data = data, aes_string(x = x, y = y, fill = fill, colour = colour)) +
    stat_summary(fun = median, show.legend = FALSE, geom="crossbar", linewidth = linewidth, colour = stat.colour, ...) +
    geom_jitter(show.legend = FALSE, width = 0.25, size = size.jitter, ...) +
    labs(x=xlab, y=ylab)
}

The make_graphs() stay like you had it, then you can just call it like this: make_graphs()保持原样,然后您可以这样调用它:

make_graphs(data = data, x = "Species", y = "Petal.Width", 
            colour = "Species", fill = "Species")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM