首页 > 解决方案 > 从一个小标题创建单独的图并将每个图分别保存在 R 中

问题描述

我是 R 新手,事实上这是我在 SO 上的第一篇文章。如果我的描述和布局不理想,我们深表歉意 - 欢迎所有反馈。

我的问题是我想从tibble数据中创建单独的图,其中每个图针对不同的国家但具有相同的变量。然后我想将每个图分别保存为 png。

我最熟悉tidyverseggplot整理数据,然后将其可视化。我创建了一个包含 4 个变量的 32,454 个观察值的小标题。数据包括 200 个不同的国家。我希望geom_bar为每个国家、每个变量(Gov_bal、Priv_bal、Ext_bal)创建单独的图。我希望stack每年每个变量的值,然后通过fill.

我看过这里https://stats.stackexchange.com/questions/19213/generate-separate-plots-for-each-group-of-records-in-dataset;这里使用 for 循环保存多个 ggplots并在此处为列中的每个变量绘制一个直方图(单独),但我无法实现我想要的。

这是我的数据示例。我确信有更好的方法可以复制它,但这是它的要点。

Country <- c("Aus", "Aus", "Aus", "Aus", "USA", "USA", "USA", "USA", "UK", "UK", "UK", "UK")
Year <- c("1990", "1991", "1992", "1993", "1990", "1991", "1992", "1993", "1990", "1991", "1992", "1993")
Gov_bal <- c(5, 6, 5, 8, 8, 9, 5, 4, 6, 7, 4, 8)
Priv_bal <- c(3, 5, 4, 2, 6, 8, 5, 3, 2, 3, 6, 5)
Ext_bal <- c(2, -1, -2, 4, 5, 1, 3, 7, 4, 2, 3, 1)

sect_balances <- data.frame(Country, Year, Gov_bal, Priv_bal, Ext_bal)

sect_balances <- sect_balances %>% pivot_longer(Gov_bal:Ext_bal, names_to = "Sector", values_to = "Value")

我想要的每个国家的情节是这样的。(我曾经filter(Country == "Aus")为这个例子只选择一个国家,但我想要一个自动为我做这件事的功能/解决方案。)

sect_balances %>% filter(Country == "Aus") %>% 
  ggplot(aes(x = Year, y = Value, fill = Sector)) +
  geom_bar(position = "stack", stat = "identity") +
    labs(x = "Year",
         y = "Per cent of GDP",
         title = "Australia") +
  theme_classic()

我也知道我可以用来facet_wrap按“国家”显示所有图,但我想单独保存每个图。

我的问题是我希望创建一个循环或其他一些解决方案,循环遍历不同的国家并创建单独的geom_bar图。因此,对于我上面的数据示例,我想要一个代码来创建三个单独的geom_bar图(例如,“Aus”、“USA”、“UK”各一个),然后分别保存每个图。显然,对于我的实际数据,我想要一个可以为 200 个不同国家/地区执行此操作的代码。

我已经尝试过这段代码,但老实说,我对函数loopmap. 我需要做更多的阅读,但任何帮助都会很棒。

for (i in Country) {
  country_id <- subset(sect_balances, Country == i) 
  p <- ggplot(country_id, aes(x = Year, y = Value)) + geom_bar(position = "stack",
                                                               stat = "identity") 
  png(paste("plot_", i, ".png", sep = ""), width = 600, height = 500, res = 120) 
  print(p) 
  dev.off() 
}

我不记得我在哪里找到了我调整的这段代码,但不幸的是它不能解决我的问题。

非常感谢

标签: rloopsggplot2purrr

解决方案


如果您想单独绘制每个国家而不是使用for循环,您可以将数据拆分为数据框列表并单独绘制每个国家。

library(tidyverse)

sect_balances %>%
  group_split(Country) %>%
  map(~ggplot(.x) + aes(x = Year, y = Value, fill = Sector) +
      geom_bar(position = "stack", stat = "identity") +
      labs(x = "Year",
           y = "Per cent of GDP",
           title = first(.x$Country)) +
      theme_classic()) -> list_plot

list_plot有地块列表,您可以单独访问它们中的每一个list_plot[[1]]list_plot[[2]]依此类推。

如果要将它们保存为设备上的单独图,可以ggsave在代码中添加其他命令:

sect_balances %>%
  group_split(Country) %>%
  map(~{ggplot(.x) + aes(x = Year, y = Value, fill = Sector) +
        geom_bar(position = "stack", stat = "identity") +
        labs(x = "Year",
             y = "Per cent of GDP",
             title = first(.x$Country)) +
        theme_classic() -> plot
      ggsave(paste0(first(.x$Country), '_plot.png'), plot)
      })

推荐阅读