1

I am trying to combine several for loops into a single loop or function. Each loop is evaluating if an individual is present at a site that is protected, and based on that is assigning a number (numbers represent sites) at each time step. After that, the results for each time step are stored in a matrix and later used in other analysis. The problem that I am having is that I am repeating the same loop several times to evaluate the different scenarios (10%, 50%, 100% of sites protected). Since I need to store my results for each scenario I can't think of a better way to simplify this into a single loop or function. Any ideas or suggestions will be appreciated. This is a very small and simplify idea of the problem. I would like to keep the structure of the loop since my original loop is using several if statements. The only thing that is changing is the proportion of sites that are protected.

N<-10 # number of sites
sites<-factor(seq(from=1,to=N))

sites10<-as.factor(sample(sites,N*1))     
sites5<-as.factor(sample(sites,N*0.5)) 
sites1<-as.factor(sample(sites,N*0.1)) 

steps<-10
P.stay<-0.9

# storing results

result<-matrix(0,nrow=steps) 
time.step<-seq(1,steps)
time.step<-data.frame(time.step)
time.step$event<-0

j<-numeric(steps)
j[1]<-sample(1:N,1)
time.step$event[1]<-j[1] 

for(i in 1:(steps-1)){

    if(j[i] %in% sites1){   

      if(rbinom(1,1,P.stay)==1){time.step$event[i+1]<-j[i+1]<-j[i]} else 

  time.step$event[i+1]<-0

  }

    time.step$event[i+1]<-j[i+1]<-sample(1:N,1)

}   

results.sites1<-as.factor(result)

###

result<-matrix(0,nrow=steps) 
time.step<-seq(1,steps)
time.step<-data.frame(time.step)
time.step$event<-0

j<-numeric(steps)
j[1]<-sample(1:N,1)
time.step$event[1]<-j[1] 

for(i in 1:(steps-1)){

  if(j[i] %in% sites5){   

    if(rbinom(1,1,P.stay)==1){time.step$event[i+1]<-j[i+1]<-j[i]} else 

      time.step$event[i+1]<-0

  }

  time.step$event[i+1]<-j[i+1]<-sample(1:N,1)

}   

results.sites5<-as.factor(result)

###

result<-matrix(0,nrow=steps) 
time.step<-seq(1,steps)
time.step<-data.frame(time.step)
time.step$event<-0

j<-numeric(steps)
j[1]<-sample(1:N,1)
time.step$event[1]<-j[1] 

for(i in 1:(steps-1)){

  if(j[i] %in% sites10){   

    if(rbinom(1,1,P.stay)==1){time.step$event[i+1]<-j[i+1]<-j[i]} else 

      time.step$event[i+1]<-0

  }

  time.step$event[i+1]<-j[i+1]<-sample(1:N,1)

}   

results.sites10<-as.factor(result)

#

results.sites1
results.sites5
results.sites10
4

1 回答 1

2

而不是这样做:

sites10<-as.factor(sample(sites,N*1))     
sites5<-as.factor(sample(sites,N*0.5)) 
sites1<-as.factor(sample(sites,N*0.1)) 

并为三个变量中的每一个运行不同的循环,您可以制作一个通用循环并将其放入一个函数中,然后使用其中一个-apply函数使用特定参数调用它。例如:

N<-10 # number of sites
sites<-factor(seq(from=1,to=N))
steps<-10
P.stay<-0.9

simulate.n.sites <- function(n) {
  n.sites <- sample(sites, n)

  result<-matrix(0,nrow=steps) 
  time.step<-seq(1,steps)
  time.step<-data.frame(time.step)
  time.step$event<-0

  j<-numeric(steps)
  j[1]<-sample(1:N,1)
  time.step$event[1]<-j[1] 

  for(i in 1:(steps-1)){

    if(j[i] %in% n.sites){ 

  ...etc...

  return(result)

}

results <- lapply(c(1, 5, 10), simulate.n.sites)

现在results将是一个包含三个矩阵元素的列表。

关键是确定你重复自己的地方,然后将这些区域重构为功能。这不仅更简洁,而且将来很容易扩展。想要为 2 个站点取样?将 2 放入您传递给的向量中lapply

如果您不熟悉-apply函数系列,请务必查看这些函数。

我还怀疑您的其他大部分代码都可以简化,但我认为您对它的理解太多了,我无法理解它。例如,您根据条件定义了一个 time.step$event 元素,但随后您覆盖了该元素。当然这不是实际代码的作用吗?

于 2013-06-01T02:28:34.273 回答