添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

KANG1943

我在一个自定义函数(下文称为函数1)中用 ggplot() 画图,然后在另外一个自定义函数(下文称为函数2)中引用了函数1,但是在执行函数2的时候,不希望生成的图片被打印出来。详情如下。

# 载入需要的包
library(ggplot2)
library(ggpubr)
# 构建数据
mydata <- data.frame(name_1 = c(1: 10), 
                     name_2 = c(11: 20), 
                     name_3 = c(111: 120))
# 函数1:以下函数能对数据的某一列作图
func_plot <- function(var_data, name) {
  # 作图参数设置
  plot_data <- ggplot() + 
    geom_point(aes(c(1:10), mydata[, name])) +
    labs(y = name)
  # 把图打出来
  print(plot_data)
func_plot(mydata, "name_1")
# 可以看到输出了一个图如下
# 函数2:以下函数能对数据的所有列作图
func_plot_df <- function(var_data) {
  # 建一个列表先存储要打印的图
  plot_ls <- vector("list")
  for (i in names(var_data)) {
    plot_ls[[i]] <- func_plot(var_data, i)
  # 然后把这些图安排在一个2 X 2的画布上
  ggarrange(plotlist = plot_ls, nrow = 2, ncol = 2)
func_plot_df(mydata)
可以看到输出四个图如下

想达到的效果是: 执行函数1的时候,能正常打印图片;而执行函数2的时候,只输出第四个图,而不输出前三个。

可能的解决方法: 目前函数2是基于函数1建立的,如果将函数1的源代码整合到函数2的源代码中并稍加修改,就可以实现我想要的效果。但是这样维护起来就比较麻烦,比如我想对函数1和函数2打印出图的样式做改变的话,就需要对两段源代码都做修改。

拓展: 这段描述跟问题本身没有关系,主要解释我为什么希望解决这个问题,可以忽略。通过这个提问想解决的问题其实是,我需要两个函数,一个是对数据框的特定列作图,而另一个是对每一列作图,并将他们排在一个2x2的画布上以便查看。后者相当于对前者功能的一个扩展:前者应用于简单向量,后者应用于数据框。甚至,我还需要在这个基础上写一个列表版本的函数,实现类似的功能,只不过打印出图的排列形式也要进行一定的精简,以便查看。

KANG1943

barnett874 哈哈哈,意外的回答。不好意思,我没说清楚哈。我是希望第一函数能打印出来图片,而第二个函数只打出第四个图片。想了一下,增加了一个输入变量,目前的解决方案是:

# 载入需要的包
library(ggplot2)
library(ggpubr)
# 构建数据
mydata <- data.frame(name_1 = c(1: 10), 
                     name_2 = c(11: 20), 
                     name_3 = c(111: 120))
# 函数1:以下函数能对数据的某一列作图
func_plot <- function(var_data, name, figure = TRUE) {
  # 作图参数设置
  plot_data <- ggplot() + 
    geom_point(aes(c(1:10), mydata[, name])) +
    labs(y = name)
  # 把图打出来
  if (figure == TRUE) {print(plot_data)} else {plot_data}
# 运行函数1,出一个大图
func_plot(mydata, "name_1")
# 函数2:以下函数能对数据的所有列作图
func_plot_df <- function(var_data) {
  # 建一个列表先存储要打印的图
  plot_ls <- vector("list")
  for (i in names(var_data)) {
    plot_ls[[i]] <- func_plot(var_data, i, figure = FALSE)
  # 然后把这些图安排在一个2 X 2的画布上
  ggarrange(plotlist = plot_ls, nrow = 2, ncol = 2)
# 运行函数2,几个分开的大图不打印,只打印最后拼出来的图
func_plot_df(mydata)
plot_ls <- vector("list") for (i in names(var_data)) { plot_ls[[i]] <- invisible(func_plot(var_data, i)) #使用invisible # 然后把这些图安排在一个2 X 2的画布上 ggarrange(plotlist = plot_ls, nrow = 2, ncol = 2) func_plot_df(mydata)

yihui

我不明白你们绕这么大一圈在干啥,直接把最初的代码中的 print() 去掉就可以了啊。下面的 invisible() 函数并不起任何作用,它只在顶层表达式中才有用: https://yihui.org/en/2017/06/top-level-r-expressions/ 用在 for 循环内的话,那就不是顶层表达式。一个表达式内部的值是不会被打印出来的,只有顶层表达式的最后一个值会打印。所以 for 循环内的这个 invisible() 有或没有都没关系,问题不是出在这里,而是最初第一个函数显式调用了 print() ,通常来说这不是编程的好习惯。除非不可避免,否则函数尽量只返回值,而不要涉及副作用(打印就是常见的副作用)。