为各种data.frames创建相同的图

时间:2017-04-12 07:50:09

标签: r ggplot2 foreach

我有三个不同的data.frames(GRCYPT_flows,ESIEIT_flows,GRCYPT_flows),它们包含相同的变量(report_ctry,partner_ctry,指标,年份,值),但具有不同的级别/观察值。现在我想为每个data.frames创建绘图。由于这些图看起来应该是相同的,所以我似乎有理由使用迭代命令。我尝试了foreach循环:

foreach(i=GRCYPT_flows, ESIEIT_flows, GRCYPT_flows) %do% {  ggplot(i, aes(year, value)) + 
geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) +
theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
scale_y_continuous(name="Billion Euros") + 
scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("EA17", "Extra-EA17")) +
scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("Trade", "Capital")) +
theme(legend.title=element_blank())}

代码实际上不起作用。我在这里遇到问题:

  1. 将data.frame分配给迭代变量。

  2. 告诉foreach循环将每个迭代保存到具有不同名称的不同列表(plot1,plot2,plot3等)。

  3. 我相对肯定,如果你对R有一些经验,这很容易解决。但我是一个全新的角斗士,所以我真的不知道从哪里开始(我可以轻松地用Stata做到这一点)我至少有一些经验)。

    我想要做的是告诉R:“为每个data.frames绘制一个图表,并将每个data.frames保存在一个单独的列表中。”

3 个答案:

答案 0 :(得分:0)

这是一个有三个虹膜数据帧的例子,为了简单起见,我将它命名为i1,i2和i3。

i2 <- i3 <- i1 <- iris

foreach(m = 1:3) %do% {
  dat <- paste0("i" , m) %>% get
  ggplot(dat, aes(Sepal.Length, Petal.Length)) + geom_line()
}

基本上,诀窍是使用get调用特定的data.frame。在你的情况下,这应该工作:

data.names <- c("GRCYPT_flows", "ESIEIT_flows", "GRCYPT_flows")
foreach(i=1:length(data.names) %do% {
  dat <- get(data.names[i])
  ggplot(dat, aes(year, value)) + 
     geom_line(aes(colour=partner_ctry, linetype=indicator)) + 
     facet_wrap(~report_ctry) +
     theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
     scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
     scale_y_continuous(name="Billion Euros") + 
     scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), 
     labels=c("EA17", "Extra-EA17")) +
     scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), 
     labels=c("Trade", "Capital")) +
     theme(legend.title=element_blank())
  }

答案 1 :(得分:0)

我认为这里最“R”-y的解决方案是lapply。 Lapply采用了一系列事物并对所有事物做了同样的事情,然后将输出存储为列表。由于你正在使用ggplot,你可能会喜欢一个整齐有序的所有相似图表的列表。

首先将您的数据框组织在一个列表中

my_data  <- list(GRCYPT_flows, ESIEIT_flows) 

您的“三个”数据框中有两个具有完全相同的名称。我假设你实际上意味着两个,但这适用于任意数量的数据帧。

my_plots = lapply(my_data, function(i) {
ggplot(i, aes(year, value))
})

这将获取列表中的每个元素(“i”)并对其执行自定义函数,其中自定义函数是您精心设计的图。

由于您使用的是ggplot,因此您可以将这些图存储为输出。所以my_plots将是一个包含所有情节的整洁列表。

所以使用完整的情节函数试试:

    my_plot <- lapply(my_data, function(i) {
ggplot(i, aes(year, value)) + 
geom_line(aes(colour=partner_ctry, linetype=indicator)) + facet_wrap(~report_ctry) +
theme(axis.text.x=element_text(angle=90, vjust=0.5)) + 
scale_x_continuous(breaks=seq(2002, 2012, 2), name="") +
scale_y_continuous(name="Billion Euros") + 
scale_colour_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("EA17", "Extra-EA17")) +
scale_linetype_discrete(breaks=c("EA17", "ROW_NON_EA17"), labels=c("Trade", "Capital")) +
theme(legend.title=element_blank())
})

答案 2 :(得分:0)

我建议将绘图代码与循环分开,这样您就可以在一个示例中测试它,然后轻松地为批处理运行它。您可能希望将批处理保存到文件中。

library(tidyverse)

myplot <- function(df, filename = NULL) {
  df %>%
    ggplot(aes(Sepal.Length, Petal.Length)) +
    geom_point() ->
    result

  if(!is.null(filename)) ggsave(filename, plot = result, width = 6, height = 4)
  else result
}

# test the plot
myplot(iris)

# do the batch
l <- list(one = iris, two = iris)
l %>% names %>% walk(function(n) myplot(l[[n]], paste0(n, ".pdf")))