【问题标题】:Why does r purrr's pmap say "Only strings can be converted to symbols" and not iterate over dataset?为什么 r purrr 的 pmap 说“只有字符串可以转换为符号”而不是遍历数据集?
【发布时间】:2021-10-21 10:26:04
【问题描述】:

我正在尝试使用 purrr 包中的 pmap 自动创建 ggplot 幻灯片。作为此question 的扩展,我正在尝试根据我的数据中的组成员变量(级别和位置)进行分面。

与上一个问题不同,我知道有 3 个输入,所以我需要使用 pmap() 而不是 map2(),并且由于某种原因我不断收到此错误:

Error: Only strings can be converted to symbols
Run `rlang::last_error()` to see where the error occurred.

当我深入研究错误时,它表明问题出在我的第一个 pmap() 调用中:

<error/rlang_error>
Only strings can be converted to symbols
Backtrace:
  1. purrr::pmap(...)
 14. rlang::sym(variable)

我已经尝试了所有组合,但我无法破解它。我希望 R 按级别和位置迭代每个图。

这是我的代码和数据:

#Packages
library(dplyr)
library(purrr)
library(ggplot2)

#Data
test <- tibble(s1 = c("Agree", "Neutral", "Strongly disagree"),
               s2rl = c("Agree", "Neutral", "Strongly disagree"),
               f1 = c("Strongly agree", "Disagree", "Strongly disagree"),
               f2rl = c("Strongly agree", "Disagree", "Strongly disagree"),
               level = c("Manager", "Employee", "Employee"),
               location = c("USA", "USA", "AUS"))

#Get just test items for name
test_items <- test %>%
  dplyr::select(s1, s2rl, f1, f2rl)

#titles of plots for R to iterate over
titles <- c("S1 results", "Results for S2RL", "Fiscal Results for F1", "Financial Status of F2RL")


#group levels
group_name <- c("level", "location")

#custom ggplot function
faceted_plots = function(variable, group, title) {

  sample_size <- test %>%
    group_by(!! rlang::sym(group), !! rlang::sym(variable)) %>%
    summarize(n = sum(!is.na(!! rlang::sym(variable))))
  

  test %>%
    count(!! rlang::sym(group), !! rlang::sym(variable)) %>%
    mutate(percent = 100*(n / sample_size$n)) %>%
    drop_na() %>%
    ggplot(aes(x = !! rlang::sym(variable), y = percent, fill = .data[[variable]])) + 
    geom_bar(stat = "identity") +
    geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
    ylab("\nPercentage") +
    labs(
      title = title,
      subtitle = paste0("(N = ", sample_size$n, ")")) +
    coord_flip() +
    theme_minimal() +
    scale_fill_manual(values = c("Strongly disagree" = "#CA001B", "Disagree" = "#1D28B0", "Neutral" = "#D71DA4", "Agree" = "#00A3AD", "Strongly agree" = "#FF8200")) +
    scale_x_discrete(labels = c("Strongly disagree" = "Strongly\nDisagree", "Disagree" = "Disagree", "Neutral" = "Neutral", "Agree" = "Agree", "Strongly agree" = "Strongly\nAgree"), drop = FALSE) + 
    theme(axis.title.y = element_blank(),
          axis.text = element_text(size = 14, color = "gray28", face = "bold", hjust = .5),
          axis.title.x = element_text(size = 18, color = "gray32", face = "bold"),
          legend.position = "none",
          text = element_text(family = "Arial"),
          plot.title = element_text(size = 20, color = "gray32", face = "bold", hjust = .5),
          plot.subtitle = element_text(size = 16, color = "gray32", face = "bold", hjust = .5),
          panel.spacing.x = unit(2, "lines")) +
    ylim(0, 100) +
    facet_grid(~!! rlang::sym(group))
}

#pmap call
plots_and_facet <- pmap(
  list(x = names(test_items),
       y= titles,
       z = group_name),
  faceted_plots(test_items, titles, group_name))

使用 Flick 先生的解决方案进行编辑——它有效!忽略任何与计数有关的问题,因为那是我的问题,超出了这个问题的范围:

#custom ggplot function
faceted_plots = function(variable, group, title) {

  sample_size <- test %>%
    group_by(.data[[group]], .data[[variable]]) %>%
    summarize(n = sum(!is.na(.data[[variable]])))
  

  test %>%
    count(.data[[group]], .data[[variable]]) %>%
    mutate(percent = 100*(n / sample_size$n)) %>%
    drop_na() %>%
    ggplot(aes(x = .data[[variable]], y = percent, fill = .data[[variable]])) + 
    geom_bar(stat = "identity") +
    geom_text(aes(label= paste0(percent, "%"), fontface = "bold", family = "Arial", size=14), vjust= 0, hjust = -.5) +
    ylab("\nPercentage") +
    labs(
      title = title,
      subtitle = paste0("(N = ", sample_size$n, ")")) +
    coord_flip() +
    theme_minimal() +
    scale_fill_manual(values = c("Strongly disagree" = "#CA001B", "Disagree" = "#1D28B0", "Neutral" = "#D71DA4", "Agree" = "#00A3AD", "Strongly agree" = "#FF8200")) +
    scale_x_discrete(labels = c("Strongly disagree" = "Strongly\nDisagree", "Disagree" = "Disagree", "Neutral" = "Neutral", "Agree" = "Agree", "Strongly agree" = "Strongly\nAgree"), drop = FALSE) + 
    theme(axis.title.y = element_blank(),
          axis.text = element_text(size = 14, color = "gray28", face = "bold", hjust = .5),
          axis.title.x = element_text(size = 18, color = "gray32", face = "bold"),
          legend.position = "none",
          text = element_text(family = "Arial"),
          plot.title = element_text(size = 20, color = "gray32", face = "bold", hjust = .5),
          plot.subtitle = element_text(size = 16, color = "gray32", face = "bold", hjust = .5),
          panel.spacing.x = unit(2, "lines")) +
    ylim(0, 100) +
    facet_grid(~.data[[group]])
}

#pmap call
expand_grid(tibble(item = names(test_items), title=titles),
              group = group_name) %>%
  pmap(function(item, group, title)
    faceted_plots(item, group, title))

【问题讨论】:

    标签: r ggplot2 purrr pmap


    【解决方案1】:

    对于pmap,您实际上需要传递一个函数,而不是为.f= 参数调用函数。此外,如果您想要所有可能的组合,您首先需要使用purrr::expand_grid 创建组合,然后再调用pmap。所以你的电话看起来像

    plots_and_facet <-
      expand_grid(tibble(item = names(test_items), title=titles),
                  group = group_name) %>%
      pmap(function(item, group, title)
        faceted_plots(item, group, title))
    

    您还有很多 !!rlang::sym(variable) 的用法,但现在推荐的方法是 .data[[variable]],您在某些地方确实有这种用法,但您应该将所有这些都更改为使用 .data 代词安全。

    【讨论】:

    • 感谢您的帮助!您的解决方案使代码运行,但有一个问题。它没有遍历所有标题,只是使用第一个标题。我编辑了我的问题以包含您的解决方案及其代码 - 您能确定它为什么不会遍历标题吗?
    • 你更新了labs(title = "Test")的那部分代码吗?确保您使用的是传递给 title 参数的值:labs(title = title)
    • 是的,我在实施您的解决方案后编辑了该部分,这就是我发现它仅对所有图表使用“S1 结果”的原因
    • 你的代码有lab(title = titles),而不是lab(title = title)。前者使用带有所有值的全局变量,后者使用传递给函数的值。
    • 原来是这样——谢谢!我已经编辑了我的代码以反映更改并将接受答案。感谢您的宝贵时间!
    猜你喜欢
    • 2020-12-02
    • 1970-01-01
    • 2011-11-24
    • 2017-11-09
    • 2023-01-05
    • 2021-12-28
    • 2014-06-27
    • 2021-11-05
    • 2020-06-02
    相关资源
    最近更新 更多