繁体   English   中英

在循环中创建多个图并保存在 R 中?

[英]Creating multiple plots within a loop and saving in R?

我无法从循环的输出中保存多个图。 提供一些背景:

我有多个数据框,每个数据框都有多个物种的单一化学毒性数据。 我已经为它所代表的化学物质标记了每个数据框,即“ChemicalX”。 数据采用这种格式,因为这就是“SSDTools”包的工作方式,它为单一化学品创建了物种敏感性分布。

因为我有很多化学品,所以我想创建一个循环来遍历每个数据帧,计算创建 SSD 所需的指标,绘制 SSD,然后保存绘图。

下面的代码用于计算所有指标并绘制 SSD - 只有当我尝试在循环中创建标题以及尝试在循环中保存绘图时才会中断

作为参考,我正在使用以下软件包:SSDTools、ggplot2、tidyverse、fitdistrplus

我的代码如下:

# Create a list of data frames 
list_dfs <- list(ChemicalX, ChemicalY, ChemicalZ)

# make the loop
for (i in list_dfs){ # for each chemical (ie data frame)
  ssd.fits <- ssd_fit_dists(i, dists = c("llogis", "gamma", "lnorm", "gompertz", "lgumbel", "weibull", "burrIII3", "invpareto", "llogis_llogis", "lnorm_lnorm")) # Test the goodness of fit using all distributions available
  ssd.gof_fits <- ssd_gof(ssd.fits) # Save the goodness of fit statistics
  chosen_dist <- ssd.gof_fits %>% # Choose the best fit distribution by 
  filter(aicc==min(aicc)) # finding the minimum aicc
  final.fit <- ssd_fit_dists(i, dists = chosen_dist$dist) # Use the chosen distribution only
  final.predict <-predict(final.fit, ci = TRUE) # generate the final predictions
  plotdata <- i # create a separate plot data frame
  final.plot <-  ssd_plot(plotdata, final.predict, # generate the final plot
                        color = "Taxa",
                        label = "Species",
          xlab = "Concentration (ug/L)", ribbon = TRUE) + 
  expand_limits(x = 10e6) + # to ensure the species labels fit
  ggtitle(paste("Species Sensitivity for",chem_names_df[i], sep = " ")) +
  scale_colour_ssd()
  ggsave(filename = paste("SSD for",chem_names_df[i], ".pdf", sep = ""),
         plot = final.plot)
}  

代码一直运行良好,直到最后一部分,我想在每次迭代中为每种化学物质创建一个标题,并且我想将文件名保存为化学名称。

我有两个问题:

  1. 我希望绘图的标题是“ChemicalX 的物种敏感性”,其中 ChemicalX 是数据框的名称。 但是,当我使用以下代码时,标题变得一团糟,并给了我该数据框中的物种列表(见图)。

     ggtitle(paste("Species Sensitivity. for",i, sep = " "))

    使用“i”的图形标题输出

    为了解决这个问题,我创建了一个与数据框列表顺序相匹配的化学名称向量,称为“chem_names_df”。 但是,当我使用ggtitle(paste("Species Sensitivity for",chem_names_df[i], sep = " "))时,它给了我错误Error in chem_names_df[i] : invalid subscript type 'list'

  2. 当我尝试使用 GGSave 保存绘图时,会发生类似的问题。 我试图将每个化学数据帧的文件名保存为“SSD_ChemicalX”,除了与上面类似,它只输出一个物种列表来代替 i。

我认为这与 R 如何从我的数据框列表中调用有关 - 我不确定它为什么调用物种列表(即c("Danio Rerio, Lepomis macrochirus,...) )而不是化学名称.

任何帮助,将不胜感激! 谢谢!

基本上你的问题是你有时使用i就好像它是一个索引,有时好像它是一个数据框,但实际上它是一个数据框。

您的示例不可重现,所以让我提供一个。 你已经完成了相当于:

list_dfs2  <- list(mtcars, mtcars, cars)

for(i in list_dfs2){
    print(i)
}

这只是要打印整个mtcars数据集两次,然后是cars数据集。 然后您可以定义一个向量:

cars_names  <- c("mtcars", "mtcars", "cars")

如果您调用cars_names[i] ,则在第一次迭代中您不会调用cars_names[1] ,而是尝试使用整个数据框对向量进行子集化。 那是行不通的。 当您想引用实际数据帧而不是索引i时,最好使用seq_along()您的数据帧列表,然后使用list_dfs[[i]]对其进行子集化。 就像是:

# Create a list of data frames 
list_dfs <- list(ChemicalX, ChemicalY, ChemicalZ)

# make the loop
for (i in seq_along(list_dfs)){ # for each chemical (ie data frame)
  ssd.fits <- ssd_fit_dists(list_dfs[[i]], dists = c("llogis", "gamma", "lnorm", "gompertz", "lgumbel", "weibull", "burrIII3", "invpareto", "llogis_llogis", "lnorm_lnorm")) # Test the goodness of fit using all distributions available
  ssd.gof_fits <- ssd_gof(ssd.fits) # Save the goodness of fit statistics
  chosen_dist <- ssd.gof_fits %>% # Choose the best fit distribution by 
  filter(aicc==min(aicc)) # finding the minimum aicc
  final.fit <- ssd_fit_dists(list_dfs[[i]], dists = chosen_dist$dist) # Use the chosen distribution only
  final.predict <-predict(final.fit, ci = TRUE) # generate the final predictions
  plotdata <- list_dfs[[i]] # create a separate plot data frame
  final.plot <-  ssd_plot(plotdata, final.predict, # generate the final plot
                        color = "Taxa",
                        label = "Species",
          xlab = "Concentration (ug/L)", ribbon = TRUE) + 
  expand_limits(x = 10e6) + # to ensure the species labels fit
  ggtitle(paste("Species Sensitivity for",chem_names_df[i], sep = " ")) +
  scale_colour_ssd()
  ggsave(filename = paste("SSD for",chem_names_df[i], ".pdf", sep = ""),
         plot = final.plot)
}  

考虑使用接收名称和数据框作为输入参数的已定义方法。 然后,使用Map命名列表传递给方法,以逐元素遍历数据帧和相应的名称:

功能

build_plot <- function(plotdata, plotname) {
  # Test the goodness of fit using all distributions available 
  ssd.fits <- ssd_fit_dists(
     plotdata, 
     dists = c(
       "llogis", "gamma", "lnorm", "gompertz", "lgumbel", "weibull", 
       "burrIII3", "invpareto", "llogis_llogis", "lnorm_lnorm"
     )
  )
  # Save the goodness of fit statistics
  ssd.gof_fits <- ssd_gof(ssd.fits) 
  # Choose the best fit distribution by finding the minimum aicc
  chosen_dist <- filter(ssd.gof_fits, aicc==min(aicc)) 
  # Use the chosen distribution only
  final.fit <- ssd_fit_dists(plotdata, dists = chosen_dist$dist)  

  # generate the final predictions  
  final.predict <- predict(final.fit, ci = TRUE) 

  # generate the final plot
  final.plot <- ssd_plot(
      plotdata, final.predict, color = "Taxa", label = "Species",
      xlab = "Concentration (ug/L)", ribbon = TRUE) + 
    expand_limits(x = 10e6) + # to ensure the species labels fit 
    ggtitle(paste("Species Sensitivity for", plotname)) + 
    scale_colour_ssd() 

  # export plot to pdf
  ggsave(filename = paste0("SSD for ", plotname, ".pdf"), plot = final.plot)

  # return plot to environment
  return(final.plot)
}

称呼

# create a named list of data frames
chem_dfs <- list(
   "ChemicalX"=ChemicalX, "ChemicalY"=ChemicalY, "ChemicalZ"=ChemicalZ
)

chem_plots <- Map(build_plot, chem_dfs, names(chem_dfs))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM