【问题标题】:automate ggplots while using variable labels as title and axis titles使用变量标签作为标题和轴标题时自动化 ggplots
【发布时间】:2020-03-24 11:41:57
【问题描述】:

我有点混淆了 NSE 和绘图功能。我试图在使用变量标签(而不是名称)标记轴等的同时自动绘制几个图。假设我们有一个大型数据集,其中所有变量都已标记。这里的小例子:

library(tidyverse)
library(sjlabelled)
library(ggplot2)
library(cowplot)
data("diamonds")
diamonds <- diamonds %>% 
  var_labels(
  cut ="nice cut",
  color = "all colours",
  clarity = "very claity all",
  depth = "test depth")

我想要的基本情节是这样的:

p1 <- ggplot(diamonds, aes(x = cut, y = depth)) + geom_boxplot(aes(fill = cut)) +
  theme_cowplot() + 
  lab(title = "Plot of test depth ~ nice cut",   #based on label variable
                           x = "nice cut",      #based on label variable
                           y = "test depth",    #based on label variable
                         fill = "nice cut")    #based on label variable
p1

我想通过循环遍历其他变量来自动化这个绘图。所以我想要vars 中的列的箱线图,分别由depth depth 以下是我正在尝试做的。

#firstly i think i should have labels separately (wondering is there a way I can use them directly from variable label?)

my_labels <-   c(
  cut = "nice cut",
  color = "all colours",
  clarity = "very claity all",
  depth = "test depth"
)

#plot function
plot_f <- function(df, x_var, y_var, x_var_label, y_var_label) {
  ggplot(df, aes(x = {{x_var}}, y = {{y_var}})) + geom_boxplot(aes(fill = {{x_var}})) +
    theme_cowplot() + labs(title = paste("Plot of", {{x_var_label}}, "~", {{y_var_label}}),
                           x = {{x_var_label}},
                           y = {{y_var_label}},
                           fill = {{x_var_label}})
}

#variables to cycle through
vars <- c("cut", "color", "clarity")
plot_list <- vars %>% 
  pmap(~plot_f(diamonds, .x, depth, my_labels)) #need to specify y_var_label & x_var_label, is there a 
#way I can just specify my_labels here?

#Finally plot lists
grid.arrange(grobs = plot_list, ncol = 1)

其他代码尝试

这就是我正在考虑的方法,我想知道我是否最好稍后尝试单独添加标签,就像使用 here 使用 plot_list$labels 所做的那样?

#Also tried a for loop which worked but the fill didnt (and also missing the variable labels)
p <- list()
for(i in vars){
  p[[i]] <- ggplot(diamonds, aes_string(x = i, y = "depth", fill = i)) + geom_boxplot() +
    #note aes_string instead of aes
    theme_cowplot()
}
grid.arrange(grobs = p, ncol = 1)

编辑

这个更简单的版本绘图,但绘图未正确捕获填充 显然缺少我想要的变量标签(粘贴等):

        #plot function
        plot_f <- function(df, x_var, y_var) {
          ggplot(df, aes(x = {{x_var}}, y = {{y_var}})) + geom_boxplot(aes(fill = {{x_var}})) +
            theme_cowplot() 
        }

        plot_f(diamonds, cut, depth )  #plots fine

#variables to cycle through
vars1 <- c("cut", "color", "clarity")
vars1
#[1] "cut"     "color"   "clarity"

#unquoted version
vars <- noquote(vars1)
vars
#[1] cut     color   clarity

    #runs
        plot_list <- vars %>% 
          map(., ~plot_f(diamonds, .x, depth))

        #plots but fill isn't correct
        grid.arrange(grobs = plot_list, ncol = 1)

任何帮助表示赞赏。

【问题讨论】:

  • @Tung 谢谢,我还没有看到你的第二个。它们非常有用,但我仍然无法弄清楚我的想法并认为它们略有不同,在您的中,您只是在 map 调用中传递变量的名称,而我希望与这些变量相关联的标签也是包含并绘制在正确的位置,而不必在我的绘图函数中包含标签作为参数......如果这有意义的话
  • 我看到这里发生了一些事情。首先,如果循环遍历字符串,{{ 代码将不适用于映射变量。我总是在开始循环之前测试我的函数,这样我才能发现这样的问题。 :) 此外,由于您需要标签名称的字符串,您可以将字符串直接传递到 labs(不需要 NSE 解决方法)。在pmap() 中,您可以循环多个输入,因此在将您的函数转换为使用字符串后,您可能需要类似pmap( list(vars, my_labels[vars], my_labels[!names(my_labels) %in% vars]), plot_f, df = diamonds, y_var = "depth") 的内容。
  • 我没有在博客上写过你在这里所做的任何复杂的事情,但我确实有一个绘图函数示例,用于同时映射变量和设置标签以与pmap() 一起使用。请参阅我添加的变量帖子starting here

标签: r function ggplot2 dplyr


【解决方案1】:

感谢 cmets @aosmith @Tung 我想出了以下解决方案:

library(cowplot)
library(gridExtra)
library(ggplot2)
library(tidyverse)

my_labels <-   c(
  cut = "nice cut",
  color = "all colours",
  clarity = "very claity all",
  depth = "test depth"
)

vars <- c("cut", "color", "clarity")

plot_f <- function(df, x_var, y_var, x_var_label, y_var_label) {
  ggplot(df, aes(x = .data[[x_var]], y = .data[[y_var]])) + 
    geom_boxplot(aes(fill = .data[[x_var]])) +
    theme_cowplot() +
    labs(title = paste("Plot of ", y_var_label, "~", x_var_label), #not .data[[]]
         x = x_var_label,
         y = y_var_label,
         fill = x_var_label)
}

#trick here is that elements of length 1 can be recycled if you wrap it in list
#https://stackoverflow.com/questions/46902461/how-to-pass-a-dataframe-and-uneven-vectors-as-parameters-in-purrr-map

plot_list <- pmap(list(df = list(diamonds), x_var = vars, y_var = list("depth"), x_var_label = my_labels[vars], 
          y_var_label = list(my_labels[!names(my_labels) %in% vars])), plot_f)

grid.arrange(grobs = plot_list, ncol = 1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2021-12-17
    • 2018-10-29
    相关资源
    最近更新 更多