在将与 map() 一起使用的函数中为 ggplot 对象添加标题

Posted

技术标签:

【中文标题】在将与 map() 一起使用的函数中为 ggplot 对象添加标题【英文标题】:Add title to ggplot objects in function that will be used with map() 【发布时间】:2022-01-19 23:43:18 【问题描述】:

我有一个函数可以做几件事,包括生成 ggplot 对象。然后我将此函数传递给 purrr::map() 以迭代嵌套数据。我需要将id 作为ggtitle 添加到我的函数中的每个ggplot 对象,但是ggplot 对象是由另一个R 包中的另一个函数创建的,所以我必须在之后添加ggtitle ggplot 对象是在我的函数中创建的。当我尝试使用 purrr::map() 进行迭代时出现错误。

我认为这个线程可能会有所帮助,但我不知道如何为我的示例编写代码:Add titles to ggplots created with map()

这是一个非常简化的函数,我认为它复制了我的问题:

library("tidyverse")

dat <- 
  structure(list(id = c("07060710", "07060710", "07060710", "07060710", 
  "07060710", "07060710", "07060710", "07060710", "07060710", "07060710", 
  "07263295", "07263295", "07263295", "07263295", "07263295", "07263295", 
  "07263295", "07263295", "07263295", "07263295"), y = c(-0.1, 
  0.1, 0, 0, -0.1, -0.1, -0.1, 0, -0.1, -0.2, 0.4, 0.5, 0.5, 0.5, 
  0.9, 0.7, 0.9, 0.9, 0.4, 0.4), x = c(1, 1.8, 1.3, 1.3, 0.7, 0.3, 
  1.5, 0.9, 1, 0.5, 1.1, 1, -0.1, -0.4, 3.2, 2.4, 3, 3.3, 0.7, 
  1)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
  -20L))

runLM = function(df) 
  # Here I try to extract the id
  # And I think this is what causes the error
  id_title <- unique(df$id)
  
  lm_fit <- lm(y ~ x, data = df)
  
  # This is a simplified plot function for this example
  # The actual initial plot is created by a function from another package
  # So I cannot manipulate the initial ggplot function
  # I can only manipulate the ggplot object after it is created
  plot_init <- 
    df %>% 
    ggplot(aes(x = x, y = y)) +
    geom_point()
  
  # Here I try to add the 'id' as a the plot title
  plot_fin <- plot_init +
    ggtitle(id_title)
  
  return(plot_fin)

然后我将这个函数传递给:

fit_lm <-
  dat %>% 
  group_by(id) %>% 
  nest() %>% 
  mutate(model = map(data, ~runLM(df = .x)))

# Here should be the plot, but I get an error when I try to iterate using map()
fit_lm[[3]][[1]]

【问题讨论】:

【参考方案1】:

嵌套后,存储在列表列data 中的数据框中没有列id。而是将参数 id_title 添加到您的函数并使用 map2 循环遍历嵌套数据的 iddata 列:

library("tidyverse")
runLM = function(df, id_title) 
  lm_fit <- lm(y ~ x, data = df)
  
  plot_init <- 
    df %>% 
    ggplot(aes(x = x, y = y)) +
    geom_point()
  
  plot_fin <- plot_init +
    ggtitle(id_title)
  
  return(plot_fin)


fit_lm <- dat %>% 
  group_by(id) %>% 
  nest() %>% 
  mutate(model = map2(data, id, ~runLM(df = .x, id_title = .y)))

fit_lm$model
#> [[1]]

#> 
#> [[2]]

【讨论】:

【参考方案2】:

另一个选项是不嵌套,而是使用group_split。然后你可以使用你原来的函数而不需要第二个参数。

也不需要使用mutate。

dat %>% 
  group_split(id) %>% 
  map(runLM)
#> [[1]]

#> 
#> [[2]]

【讨论】:

很好,很好的提醒。我已经习惯了nest/split+ map/lapply,以至于我总是忘记dplyr 现在也为这些用例提供了一些选项。 (: @tjebo 你可以打电话给map(runLM)而不是map(~runLM(df = .x)) @jpdugo17 当然。好点,谢谢!使其语法更加整洁。

以上是关于在将与 map() 一起使用的函数中为 ggplot 对象添加标题的主要内容,如果未能解决你的问题,请参考以下文章

Array.map 中的 React 功能组件在将函数作为道具传递时总是重新渲染

工具栏将与所有内容一起滚动。否则不起作用

为啥 async.map 函数可以与本机 fs.stat 函数一起使用?

Xamarin Studio 5 将与 Xcode 6 Beta 一起使用吗?

UIButton 约束失败,但适用于 UILabel

Javascript,类型错误:Information.map 不是函数 ||如何使用.map?