【问题标题】:calling a user-defined function inside a loop to generate custom plots in ggplot2在循环中调用用户定义的函数以在 ggplot2 中生成自定义图
【发布时间】:2020-10-06 17:40:56
【问题描述】:

以下是为我的问题提供上下文的示例数据集:

df <- tibble(x1 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             x2 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             x3 = factor(sample(letters[1:6], 50, replace = T), levels=letters[1:6]),
             )

head(df)

我编写了以下函数来生成一个我想在 ggplot2::ggplot() 调用中使用的新 tibble:


plot_data_prep <- function(dsn, pvar){

  pvar <- enquo(pvar)


  #convert the new plot_df and get it ready for plotting.
  plot_data <- dsn %>% 
    group_by(!!pvar) %>% count(.drop = F) %>% ungroup() %>% 
    mutate(pct = n/sum(n)*100,
         pct_lab = paste0(format(pct, digits = 1),'%'),
         pct_pos = pct + 0.6)

  return(plot_data)

}

plot_data_prep(df, x3)

我可以在制作单独的绘图时使用这个用户定义的函数:


ggplot(plot_data_prep(df,x3), mapping = aes(x=x3, y=pct))+
  geom_bar(stat = 'identity') +
  geom_text(aes(x = x3, y = pct_pos, label = pct_lab ))

但是当我尝试使用我的 plot_data_prep() 函数为每个变量生成单独的图时,在数据帧“df”中循环访问变量“x1”、“x2”和“x3”时,出现错误: '错误:列 i 未知'


df_names <- names(df)

for (i in df_names){
    plot <- ggplot(plot_data_prep(df, i), mapping = aes_string(x=i, y='n')) +
      geom_bar(stat = 'identity') +
      geom_text(aes(x = i, y = pct_pos, label = pct_lab ))

  print(plot)
}

我希望有人能够帮助我理解为什么我的 for 循环索引变量 'i' 没有解决我需要它来使我的代码工作的方式。

谢谢。

【问题讨论】:

  • 看起来你需要 aes_string() 在文本层以及全局美学。

标签: r loops ggplot2


【解决方案1】:

更改您的函数以改为接受字符串输入。

library(dplyr)
library(ggplot2)
library(rlang)

plot_data_prep <- function(dsn, pvar){

  #convert the new plot_df and get it ready for plotting.
  plot_data <- dsn %>% 
                 group_by(!!sym(pvar)) %>% count(.drop = F) %>% ungroup() %>% 
                 mutate(pct = n/sum(n)*100,
                        pct_lab = paste0(format(pct, digits = 1),'%'),
                        pct_pos = pct + 0.6)

   return(plot_data)

}

确认它有效:

plot_data_prep(df, 'x1')

现在您可以遍历名称并将图存储在列表中。

df_names <- names(df)
plot_list <- vector('list', length(df_names))

for (i in seq_along(df_names)) {
   plot <- ggplot(plot_data_prep(df, df_names[i]), 
                  mapping = aes(x= !!sym(df_names[i]), y=n)) +
           geom_bar(stat = 'identity') +
           geom_text(aes(x = !!sym(df_names[i]), y = pct_pos, label = pct_lab ))
  plot_list[[i]] <- plot
  print(plot)
}

可以通过plot_list[[1]]plot_list[[2]] 等访问各个地块。

【讨论】:

    猜你喜欢
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    相关资源
    最近更新 更多