在R中的列表中添加行

时间:2018-02-16 02:53:24

标签: r

考虑以下代码,解决了诸如Lotka-Volterra之类的DE系统。它将解决方案存储在一个名为“out”的列表中,用于4种不同的情况。我有两个问题:

(1)如何计算4个案例的每个时间步的行数并存储到向量中?我尝试使用apply(out[[i]][,1:2],1,sum),但它会产生如下错误

FUN中的错误(newX [,i],...):无效的“类型”(列表)

(2)您能解释输出的结构吗?以及为什么它与矩阵一起工作时不起作用。我尝试使用随机数创建类似的列表,但无法重现类似的结构。

感谢。

rm(list=ls())
library("foreach")
library("deSolve")
library(doParallel)
cl<-makeCluster(2, outfile = "debug.txt")
registerDoParallel(cl)

CASES = 4

LVmod <- function(Time, State, Pars) {
   with(as.list(c(State, Pars)), {
         Ingestion    <- rIng  * Prey * Predator
         GrowthPrey   <- rGrow * Prey * (1 - Prey/K)
         MortPredator <- rMort * Predator

        dPrey        <- GrowthPrey - Ingestion
        dPredator    <- Ingestion * assEff - MortPredator

        return(list(c(dPrey, dPredator)))
   })
   }

   solveODE<-function(times, LVmod, pars, yini, CASES){
   output<-foreach(x=1:CASES, .packages=c('deSolve'))  %dopar%
{
      if (x<CASES) ode(yini[[x%%CASES]], times, LVmod, pars)
      else         ode(yini[[CASES]], times, LVmod, pars)

 }
  }
     pars  <- c(rIng   = 0.2,    # /day, rate of ingestion
       rGrow  = 1.0,    # /day, growth rate of prey
       rMort  = 0.2 ,   # /day, mortality rate of predator
       assEff = 0.5,    # -, assimilation efficiency
       K      = 10)     # mmol/m3, carrying capacity

yini<-list()
yini[[1]]<-c(Prey = 1, Predator = 2)
yini[[2]]<-c(Prey = 5, Predator = 5)
yini[[3]]<-c(Prey = 2, Predator = 3)
yini[[4]]<-c(Prey = 4, Predator = 2)


out<-list()
for (i in 1:CASES) out[[i]]<-list()


for (i in 0:20){
   times <- seq(10*i, 10*(i+1), by = 1)

 output<-solveODE(times, LVmod, pars, yini, CASES)

 for (j in 1:CASES){
  out[[j]]<-rbind(out[[j]],output[[j]])
  ic11<-out[[j]][length(out[[j]][,1]),2]
  ic12<-out[[j]][length(out[[j]][,1]),3]
  yini[[j]]  <- c(Prey = as.numeric(ic11), Predator = as.numeric(ic12))
 }

}

  stopCluster(cl)

1 个答案:

答案 0 :(得分:2)

  1. 使用lapply代替apply来循环遍历list元素;例如,要为每个列表元素计算第二列Prey中值的总和,您可以执行以下操作:

    lapply(out, function(x) sum(as.numeric(x[, 2])))
    #[[1]]
    #[1] 468.3304
    #
    #[[2]]
    #[1] 461.0533
    #
    #[[3]]
    #[1] 464.6915
    #
    #[[4]]
    #[1] 469.421
    
  2. 至于你的第二个问题:&#34;你能解释一下输出的结构吗?&#34; 好吧,考虑到这是你的代码,这实际上是应该知道的东西,不是它。根据您的代码,您正在构建list list s:

    out<-list()
    for (i in 1:CASES) out[[i]]<-list()
    
  3. PS。你真的应该正确格式化你的代码。使用适当的缩进,对齐括号等。这将使您的代码更容易阅读!

    更新

    如果您想为每个Prey计算Predatortime的总和,可以在rowSums内使用lapply

    lst <- lapply(out, function(x) rowSums(as.data.frame(matrix(unlist(x), ncol = 3))[, 2:3]))
    

    as.data.frame(matrix(unlist(x), ncol = 3))将您的list转换为data.frame

    您可以使用listcbind条目进行列绑定:

    df <- do.call(cbind, lst));
    head(df);
    #         [,1]      [,2]     [,3]     [,4]
    #[1,] 3.000000 10.000000 5.000000 6.000000
    #[2,] 3.490136  9.051351 5.445284 7.034600
    #[3,] 4.359623  8.130653 5.915932 7.644949
    #[4,] 5.467660  7.246250 6.317925 7.842548
    #[5,] 6.517990  6.444182 6.589044 7.730863
    #[6,] 7.255411  5.759818 6.711389 7.420815
    

    行对应不同的time值,不同的CASES列。