【问题标题】:Converting the outputs of a for loop from a list to a data frame将 for 循环的输出从列表转换为数据框
【发布时间】:2021-08-21 01:29:47
【问题描述】:

我已经使用函数内的循环构建了一个离散时间 SIR 模型(我在下面添加了我的代码)。

目前迭代的结果以列表形式出现,似乎首先显示所有 S 值,然后是 I 值,然后是 R 值,这是我从值的性质推断出来的。

我需要将输出作为数据框的列名:从左到右的“迭代”、“S”、“I”和“R”以及下面的相应值,这样当读取一行时它会告诉您在该迭代中 S、I 和 R 的迭代和值。

我不知道如何构建一个以这种方式返回输出值的数据框,我几周前才开始学习 R,所以还不精通,因此非常感谢任何帮助。

提前谢谢你。

#INITIAL CONDITIONS 
S=999
I=1
R=0

#PARAMETERS 
beta  = 0.003 # infectious contact rate (/person/day)
gamma = 0.2 # recovery rate (/day)

#SIR MODEL WITH POISSON SAMPLING 
discrete_SIR_model <- function(){
for(i in 1:30){ #the number of iterations of loop indicates the 
  #duration of the model in days 
  # i.e. 'i in 1:30' constitutes 30 days

  deltaI<- rpois(1,beta * I * S) #rate at which individuals in the 
  #population are becoming infected
  
  deltaR<-rpois(1,gamma * I)#rate at which infected individuals are
  #recovering 
  
  S[i+1]<-S[i] -deltaI
  I[i+1] <-I[i] + deltaI -deltaR
  R[i+1]<-R[i]+deltaR
}
}
output <- list(c(S, I, R))
output

【问题讨论】:

    标签: r list dataframe for-loop


    【解决方案1】:

    如果使用了for循环,可以预先定义向量或数据框来存储结果:

    beta  <- 0.001 # infectious contact rate (/person/day)
    gamma <- 0.2   # recovery rate (/day)
    
    S <- I <- R <- numeric(31)
    
    S[1] <- 999
    I[1] <- 1
    R[1] <- 0
    
    set.seed(123) # makes the example reproducible
    for(i in 1:30){
      deltaI <- rpois(1, beta * I[i] * S[i])
      deltaR <- rpois(1, gamma * I[i])
    
      S[i+1] <- S[i] - deltaI
      I[i+1] <- I[i] + deltaI - deltaR
      R[i+1] <- R[i] + deltaR
    }
    
    output <- data.frame(S, I, R)
    output
    matplot(output)
    

    作为替代方案,也可以为此使用包。软件包 deSolve 用于微分方程,但它也可以使用“euler”方法求解离散情况:

    library(deSolve)
    
    discrete_SIR_model <- function(t, y, p) {
      with(as.list(c(y, p)), {
        deltaI <- rpois(1, beta * I * S)
        deltaR <- rpois(1, gamma * I)
        list(as.double(c(-deltaI, deltaI - deltaR,  deltaR)))
      })
    }
    
    y0 <- c(S = 999.0, I=1, R=0)
    
    p <- c(
      beta  = 0.001, # infectious contact rate (/person/day)
      gamma = 0.2    # recovery rate (/day)
    )
    
    times <- 1:30
    
    set.seed(576) # to make the example reproducible
    output <- ode(y0, times, discrete_SIR_model, p, method="euler")
    
    plot(output, mfrow=c(1,3))
    
    

    注意:我降低了 beta,否则离散模型会变得不稳定。

    【讨论】:

    • 完美,非常感谢!我想我会使用你建议的第一种方法,但我也能理解第二种方法是如何适用的。一个问题:在您放置 S
    • 感谢您的反馈。 numeric(31) 创建一个包含 31 个元素的向量来存储数据。还有很多其他(和更好的)方法可以接近。我的目标是保持简单,接近你的原始,但我建议在开始时初始化一个数据框或矩阵,而不是 3 个向量。这样就更通用,也更容易扩展。 关于您的模型的一个重要说明:您始终为整个人口绘制泊松随机数。这是正确的吗?我认为每个人都有自己的随机机会。可以考虑为个人工作。
    • 嗯,我明白了……谢谢你的帮助和建议。是的,目前我仍在假设大规模行动并为整个人口绘制泊松随机数,但我的目标是按照您的正确建议将其扩展到个人身上。
    猜你喜欢
    • 1970-01-01
    • 2016-01-28
    • 2019-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多