为什么我不能迭代地将 ggplot 对象添加到列表中?

问题描述 投票:0回答:1

我已经被这个问题困扰了一段时间。这是较大代码的简化版本。

lc(df, months=c('May', 'June', 'August'))

这应该给我相同的情节 3 次。它给了我 3 个不同的图,其中 2 个不正确。我什至无法理解正在发生的事情。当我在循环中简单地

print(p)
时,它就完美地工作了。为什么这不起作用?感谢您的任何建议。

library(dplyr)
library(ggplot2)
library(ecotox)
df <- ecotox::lamprey_tox
lc<- function(data, dose='dose', months=c(), month='month', total='total', response='response'){

  data <- data%>% filter(month %in% c(months))

  myplots <- list()
  for (i in seq_along(months)){

    a <- data[data$month %in% months[i],]
    print(a)
    lc <- LC_probit((response/ total) ~ log10(as.numeric(dose)), p = c(50, 90),
                    weights = total,
                    data =a)
    LC50 <- lc$dose[1] #strip lc50
    LC90 <- lc$dose[2] #strip lc90
    p <- ggplot(data=a,aes(x=log10(as.numeric(dose)),y=(response/total)))+
             geom_point(size=4)+ 
             geom_smooth(method="glm", 
                         method.args=list(family=binomial(link="probit")), 
                         aes(weight=total),colour="blue",se=TRUE, level=0.95) +
             geom_segment(aes(x = log10(LC50), xend = log10(LC50), y=-Inf, yend=0.5), linetype='dashed', size=1) +
             geom_segment(aes(x = -Inf, xend = log10(LC50), y=0.5, yend=0.5), linetype='dashed', size=1) +
             geom_segment(aes(x = log10(LC90), xend = log10(LC90), y=-Inf, yend=0.9), linetype='dashed', size=1) +
             geom_segment(aes(x = -Inf, xend = log10(LC90), y=0.9, yend=0.9), linetype='dashed', size=1) 
 

myplots[[i]] <- p
  print(myplots[1]) 

    
    
  }
 
}



r ggplot2
1个回答
0
投票

您得到三个不同图的原因是您在每次迭代中过滤掉不同的数据子集。

我已将另一个

print()
插入到循环中。

lc <- function(data, dose='dose', months=c(), month='month', total='total', response='response') {
  data <- data%>% filter(month %in% c(months))
  
  myplots <- list()
  
  for (i in seq_along(months)){
    print(paste("Plotting data for", months[i]))
    a <- data[data$month %in% months[i],]
    
    lc <- LC_probit(
      (response/ total) ~ log10(as.numeric(dose)), p = c(50, 90),
      weights = total,
      data =a
    )
    LC50 <- lc$dose[1]
    LC90 <- lc$dose[2]
    
    myplots[[i]] <- ggplot(
      data=a,
      aes(x=log10(as.numeric(dose)),y=(response/total))
    )+
      geom_point(size=4)+ 
      geom_smooth(
        method="glm", 
        method.args=list(family=binomial(link="probit")), 
        aes(weight=total),colour="blue",se=TRUE, level=0.95
      ) +
      geom_segment(aes(x = log10(LC50), xend = log10(LC50), y=-Inf, yend=0.5), linetype='dashed', size=1) +
      geom_segment(aes(x = -Inf, xend = log10(LC50), y=0.5, yend=0.5), linetype='dashed', size=1) +
      geom_segment(aes(x = log10(LC90), xend = log10(LC90), y=-Inf, yend=0.9), linetype='dashed', size=1) +
      geom_segment(aes(x = -Inf, xend = log10(LC90), y=0.9, yend=0.9), linetype='dashed', size=1) 
  }
  
  myplots
}

lc(df, months=c('May', 'June', 'August'))
的输出如下所示:

[1] "Plotting data for May"
[1] "Plotting data for June"
[1] "Plotting data for August"

原因是这样的:

a <- data[data$month %in% months[i],]

在第一次迭代中,提取 5 月份的数据,然后在下一次迭代中提取 6 月份的数据,最后提取 7 月份的数据。由于这几个月的数据不同,所以图表也不同。

要验证这一点,请将过滤行更改为:

a <- data[data$month %in% months[i],]

现在您得到三幅图,所有这些都基于 5 月份的数据。

了解您想要实现的目标会很有帮助。当前的实现对我来说很有意义,因为您使用的是数据的三个不同子集,所以我期望三个不同的图。

© www.soinside.com 2019 - 2024. All rights reserved.