对于循环的每次迭代,如何 return 来自 R 中函数的多个值?简单的生活史模拟

How to return multiple values from a function in R for each iteration of a loop? Simple life history simulation

我正在尝试 return 来自函数的三个变量(walkpopcathpopabovepop),用于其他变量的每个组合的循环的每次迭代在数据中;这个功能是一个生活史模拟器。我可以 return 一次在数据框中为我的一个变量创建正确的输出;我的完整工作代码示例 returns 是 walkpop 所需的输出。但是,我希望一次全部完成,而无需复制和粘贴并更改 returned 的变量。我已经看到并未能成功地尝试改编以下示例但未成功:, How to assign from a function which returns more than one value?, and Return multiple values from apply() function in R.

完成我需要的一部分的工作代码示例:

library(tidyverse)

#### Create data - Populate all possible combinations of survival and transition rates ####
walksurv = c(0.9269106, 0.970851)
cathsurv = c(.8)
abovesurv = c(0.8334328, 0.9708581)
walktrans_out_A = c(0.0343630, 0.0835229)
walktrans_out_C = c(0.0048465, 0.0273910)
walktrans_in_A = c(0.0768314, 0.2521549)
walktrans_in_C = c(0.0016355, 0.0779052)
abovetrans_out_C = c(0.0142056, 0.1188569)
cathtrans_out_A = c(0)

data = expand.grid(walksurv, cathsurv,
                   abovesurv, walktrans_out_C,
                   walktrans_out_A, walktrans_in_A,
                   walktrans_in_C, abovetrans_out_C,
                   cathtrans_out_A )
colnames(data) = c("walksurv", "cathsurv",
                   "abovesurv", "walktrans_out_C",
                   "walktrans_out_A", "walktrans_in_A",
                   "walktrans_in_C", "abovetrans_out_C",
                   "cathtrans_out_A")

#### Define intial population size ####
walkpop = 10000
abovepop = 1000
cathpop = 100

#### Make life history table function ####
getMC <- function(data){
  walkpop = walkpop*data$walksurv
  cathpop = cathpop*data$cathsurv
  abovepop = abovepop*data$abovesurv
  walkpop_pre_trans = walkpop
  walkpop = walkpop - walkpop_pre_trans*data$walktrans_out_C - walkpop_pre_trans*data$walktrans_out_A
  return(walkpop)

}
#### estimate population change across 13 time steps saving each time step####    
walkpoplist = list()
for (i in 1:13) {
  walkpop = getMC(data)
  walkpoplist[[i]] = walkpop #only works if return is same as variable in return stament

}

poplistwalk = do.call(rbind, lapply(walkpoplist, function(x) as.data.frame(t(x[1:128]))))

感谢任何帮助。

您可以 return 来自 getMC 函数的数据框。也不要依赖全局环境中的向量(walkpopcathpop 等)将它们传递给函数。

getMC <- function(data, ref_data){
   walkpop = ref_data$walkpop*data$walksurv
   cathpop = ref_data$cathpop*data$cathsurv
   abovepop = ref_data$abovepop*data$abovesurv
   walkpop_pre_trans = walkpop
   walkpop = walkpop - walkpop_pre_trans*data$walktrans_out_C - 
                       walkpop_pre_trans*data$walktrans_out_A
   return(data.frame(walkpop, cathpop, abovepop))
}


walkpop = 10000
abovepop = 1000
cathpop = 100
ref_data <- data.frame(walkpop, abovepop, cathpop)

totallist = vector('list', 2)
for (i in 1:2) {
  ref_data <- getMC(data, ref_data)
  totallist[[i]] <- ref_data
}

检查输出。

lapply(totallist, head)
#[[1]]
#   walkpop cathpop abovepop
#1 8905.669      80 833.4328
#2 9327.844      80 833.4328
#3 8905.669      80 970.8581
#4 9327.844      80 970.8581
#5 8696.702      80 833.4328
#6 9108.971      80 833.4328

#[[2]]
#   walkpop cathpop abovepop
#1 7931.094      64 694.6102
#2 8700.868      64 694.6102
#3 7931.094      64 942.5655
#4 8700.868      64 942.5655
#5 7563.262      64 694.6102
#6 8297.335      64 694.6102