R 绘制附加输入中给出的特定图形(ggplot)

R 绘制附加输入中给出的特定图形(ggplot),r,ggplot2,R,Ggplot2,我有我解决过的问题,但我认为我的解决方案是在处理更多变量时涉及到更多的问题,而且没有效率。我想写一个结合了三个图形的函数: 来自标准正态分布的数字 来自标准均匀分布的数字 来自标准指数分布的数字 可以指定样本的长度。同样在输出中,我希望有一个名为plot_types的额外输入。默认情况下,它将合并所有图形。但用户也可以指定应该包括哪些绘图。例如,如果plot_types==c'Norm.plot',则'Unif.plot'R应仅绘制正态分布和均匀分布中的数字,而忽略指数分布中的数字 我目前的工作

我有我解决过的问题,但我认为我的解决方案是在处理更多变量时涉及到更多的问题,而且没有效率。我想写一个结合了三个图形的函数:

来自标准正态分布的数字

来自标准均匀分布的数字

来自标准指数分布的数字

可以指定样本的长度。同样在输出中,我希望有一个名为plot_types的额外输入。默认情况下,它将合并所有图形。但用户也可以指定应该包括哪些绘图。例如,如果plot_types==c'Norm.plot',则'Unif.plot'R应仅绘制正态分布和均匀分布中的数字,而忽略指数分布中的数字

我目前的工作

我编写了以下代码:

library(ggplot2)
library(gridExtra)

visual=function(num,plot_types='all'){
  Norm.plot <- ggplot()+
    geom_line(aes(x=1:num,y=rnorm(num)))+
    labs(title='Norm plot',x=NULL,y=NULL)+ 
    theme(plot.title = element_text(hjust = 0.5))
  
  Unif.plot <- ggplot()+
    geom_line(aes(x=1:num,y=runif(num)))+
    labs(title='Unif plot',x=NULL,y=NULL)+ 
    theme(plot.title = element_text(hjust = 0.5))
  
  Exp.plot <- ggplot()+
    geom_line(aes(x=1:num,y=rexp(num)))+
    labs(title='Exp plot',x=NULL,y=NULL)+ 
    theme(plot.title = element_text(hjust = 0.5))
  
  if (plot_types=='all'){grid.arrange(Norm.plot,Exp.plot, Unif.plot,ncol=2)}
  else if (plot_types==c('Norm.plot','Unif.plot') || 
           plot_types==c('Unif.plot','Norm.plot')){grid.arrange(Norm.plot, Unif.plot)}
  else if (plot_types==c('Norm.plot','Exp.plot') ||
           plot_types==c('Exp.plot','Norm.plot')){grid.arrange(Norm.plot, Exp.plot)}
  else if (plot_types==c('Unif.plot','Exp.plot') || 
           plot_types==c('Exp.plot','Unif.plot')){grid.arrange(Exp.plot, Unif.plot)}
}

visual(50,plot_types = c('Norm.plot','Unif.plot'))
上面的代码有几个问题。第一个原因是它有很多循环,所以效率很低。而且,当试图将其扩展到更多的变量时,这将是非常有问题的


你知道我怎么可以省略使用这么多循环吗?

看看这是否适合你的需要

visual.new <- function(num, plot_types = 'all') {
  # define a data frame for all the results
  data <- data.frame(x = seq(1, num),
                     y.norm = rnorm(num),
                     y.unif = runif(num),
                     y.exp = rexp(num))

  # define a base ggplot object
  gg <- ggplot(data, aes(x = x)) + 
    geom_line() +
    theme(plot.title = element_text(hjust = 0.5),
          axis.title = element_blank())

  # define a list of plots
  plot.list <- list(gg + aes(y = y.norm) + ggtitle("Norm plot"),
                    gg + aes(y = y.unif) + ggtitle("Unif plot"),
                    gg + aes(y = y.exp) + ggtitle("Exp plot"))

  # initial default: do not show any plot
  show.plot <- c(FALSE, FALSE, FALSE)

  # determine whether to show all / any plot based on plot_types value
  if('all' %in% plot_types) {
    show.plot <- c(TRUE, TRUE, TRUE)
  } else {
    if('Norm.plot' %in% plot_types) show.plot[1] <- TRUE
    if('Unif.plot' %in% plot_types) show.plot[2] <- TRUE
    if('Exp.plot' %in% plot_types) show.plot[3] <- TRUE
  }
  
  if(sum(show.plot) == 0) {
    message("Invalid plot_types parameter entered. No plot shown.")
  } else {
    cowplot::plot_grid(plotlist = plot.list[show.plot])
  }
}

我使用cowplot包中的plot_grid,而不是gridExtra的grid.arrange,因为前者可以接受ggplot对象列表,这在这里很有用。

看看这是否适合您的需要

visual.new <- function(num, plot_types = 'all') {
  # define a data frame for all the results
  data <- data.frame(x = seq(1, num),
                     y.norm = rnorm(num),
                     y.unif = runif(num),
                     y.exp = rexp(num))

  # define a base ggplot object
  gg <- ggplot(data, aes(x = x)) + 
    geom_line() +
    theme(plot.title = element_text(hjust = 0.5),
          axis.title = element_blank())

  # define a list of plots
  plot.list <- list(gg + aes(y = y.norm) + ggtitle("Norm plot"),
                    gg + aes(y = y.unif) + ggtitle("Unif plot"),
                    gg + aes(y = y.exp) + ggtitle("Exp plot"))

  # initial default: do not show any plot
  show.plot <- c(FALSE, FALSE, FALSE)

  # determine whether to show all / any plot based on plot_types value
  if('all' %in% plot_types) {
    show.plot <- c(TRUE, TRUE, TRUE)
  } else {
    if('Norm.plot' %in% plot_types) show.plot[1] <- TRUE
    if('Unif.plot' %in% plot_types) show.plot[2] <- TRUE
    if('Exp.plot' %in% plot_types) show.plot[3] <- TRUE
  }
  
  if(sum(show.plot) == 0) {
    message("Invalid plot_types parameter entered. No plot shown.")
  } else {
    cowplot::plot_grid(plotlist = plot.list[show.plot])
  }
}

我使用cowplot包中的plot_grid,而不是gridExtra的grid.arrange,因为前者可以接受ggplot对象列表,这在这里很有用。

指出@Z.Lin的奇妙解决方案,您也可以使用patchwork中的wrap_plots功能。我从惊奇@Z.Lin获取了智能功能,并添加了一个小小的更改。代码如下:

#Code
visual.new <- function(num, plot_types = 'all') {
  # define a data frame for all the results
  data <- data.frame(x = seq(1, num),
                     y.norm = rnorm(num),
                     y.unif = runif(num),
                     y.exp = rexp(num))
  
  # define a base ggplot object
  gg <- ggplot(data, aes(x = x)) + 
    geom_line() +
    theme(plot.title = element_text(hjust = 0.5),
          axis.title = element_blank())
  
  # define a list of plots
  plot.list <- list(gg + aes(y = y.norm) + ggtitle("Norm plot"),
                    gg + aes(y = y.unif) + ggtitle("Unif plot"),
                    gg + aes(y = y.exp) + ggtitle("Exp plot"))
  
  # initial default: do not show any plot
  show.plot <- c(FALSE, FALSE, FALSE)
  
  # determine whether to show all / any plot based on plot_types value
  if('all' %in% plot_types) {
    show.plot <- c(TRUE, TRUE, TRUE)
  } else {
    if('Norm.plot' %in% plot_types) show.plot[1] <- TRUE
    if('Unif.plot' %in% plot_types) show.plot[2] <- TRUE
    if('Exp.plot' %in% plot_types) show.plot[3] <- TRUE
  }
  
  if(sum(show.plot) == 0) {
    message("Invalid plot_types parameter entered. No plot shown.")
  } else {
    patchwork::wrap_plots(plot.list[show.plot])
  }
}
使用@Z.Lin的奇妙代码进行一些测试:

visual.new80,c'Exp.plot',Unif.plot,Norm.plot

输出:


指出@Z.Lin的奇妙解决方案,您还可以使用patchwork中的wrap_plots函数。我从惊奇@Z.Lin获取了智能功能,并添加了一个小小的更改。代码如下:

#Code
visual.new <- function(num, plot_types = 'all') {
  # define a data frame for all the results
  data <- data.frame(x = seq(1, num),
                     y.norm = rnorm(num),
                     y.unif = runif(num),
                     y.exp = rexp(num))
  
  # define a base ggplot object
  gg <- ggplot(data, aes(x = x)) + 
    geom_line() +
    theme(plot.title = element_text(hjust = 0.5),
          axis.title = element_blank())
  
  # define a list of plots
  plot.list <- list(gg + aes(y = y.norm) + ggtitle("Norm plot"),
                    gg + aes(y = y.unif) + ggtitle("Unif plot"),
                    gg + aes(y = y.exp) + ggtitle("Exp plot"))
  
  # initial default: do not show any plot
  show.plot <- c(FALSE, FALSE, FALSE)
  
  # determine whether to show all / any plot based on plot_types value
  if('all' %in% plot_types) {
    show.plot <- c(TRUE, TRUE, TRUE)
  } else {
    if('Norm.plot' %in% plot_types) show.plot[1] <- TRUE
    if('Unif.plot' %in% plot_types) show.plot[2] <- TRUE
    if('Exp.plot' %in% plot_types) show.plot[3] <- TRUE
  }
  
  if(sum(show.plot) == 0) {
    message("Invalid plot_types parameter entered. No plot shown.")
  } else {
    patchwork::wrap_plots(plot.list[show.plot])
  }
}
使用@Z.Lin的奇妙代码进行一些测试:

visual.new80,c'Exp.plot',Unif.plot,Norm.plot

输出:


为什么你认为包裹图比网格图好@约翰你好,约翰,我只是提出一个选择。wrap_plots类似于plot_grid的改进,它具有更高级的功能。因此,OP在任何修改的情况下都可以有不同的选项:为什么您认为wrap_plots比plot_grid更好@约翰你好,约翰,我只是提出一个选择。wrap_plots类似于plot_grid的改进,它具有更高级的功能。因此,在进行任何修改时,OP可以有不同的选项: