r - 如何在for循环中迭代参数

标签 r for-loop iteration parameter-passing

我有一个编写为 for 循环的模型,其中包含我指定的许多参数:

## functions needed to run the model
learn <- function(prior, sensi, speci, e){
  out <- ifelse(e == 1, (sensi*prior) / ((sensi*prior) + (1-speci)*(1-prior)),
                ((1-sensi)*prior) / (((1-sensi)*prior) + (speci*(1-prior))))
  out
}

feed <- function(vec){
  prior <- 0.5
  for (i in vec){
    res <- learn(prior, sensi, speci, i)
    prior <- res
  }
  return(prior)
}

## specify parameters
iterations <- 100
N <- 10
BR <- 0.66
sensi <- 0.75
speci <- 0.45

## initialize results object
res <- NULL

## loop for number of iterations
for (j in 1:iterations){
  
  X <- as.numeric(rbinom(1, 1, BR))
  
  if (X == 1){ # if X is 1...
    agents <- c(1:N) 
    evidence <- vector("list", length(agents)) 
    for (i in agents) {
      n <- sample(10, 1, replace = TRUE) 
      evidence[[i]] <- rbinom(n, 1, sensi) 
    }
  } else { # if X is 0... 
    agents <- c(1:N)
    evidence <- vector("list", length(agents)) 
    for (i in agents) {
      n <- sample(10, 1, replace = TRUE) 
      evidence[[i]] <- rbinom(n, 1, sensi) 
      evidence[[i]] <- ifelse(evidence[[i]]==1, 0, 1) # flip evidence 
    }
  }
  
  # feed vectors of evidence through learn function
  t0 <- sapply(evidence, feed)
  
  # save dataframe 
  df <- data.frame("i" = j, 
                   "ID" = c(1:N), 
                   "E" = t0, 
                   "X" = X,
                   "N" = N, 
                   "BR" = BR,
                   "sensi" = sensi,
                   "speci" = speci)

  res <- rbind(res, df)
  
}

这对于单个参数化来说效果很好,但我现在想要自动化指定不同参数值并重新运行模型的过程。因此,我不是将每个参数定义为单个值,而是将它们定义为值向量,并将所有可能的参数化存储在数据帧 (paramspace) 中,每行保存我所使用的单个参数化的值。想要运行:

## set up for multiple parameterizations 
iterations <- 100
N_vec <- c(10, 50)
BR_vec <- c(0.25, 0.50, 0.75) 
sensi_vec <- c(0.45, 0.75)
speci_vec <- c(0.45, 0.75)

paramspace <- expand.grid(iterations = iterations, N = N_vec, BR = BR_vec, sensi = sensi_vec, speci = speci_vec)

> paramspace
   iterations  N   BR sensi speci
1         100 10 0.25  0.45  0.45
2         100 50 0.25  0.45  0.45
3         100 10 0.50  0.45  0.45
4         100 50 0.50  0.45  0.45
5         100 10 0.75  0.45  0.45
6         100 50 0.75  0.45  0.45
7         100 10 0.25  0.75  0.45
8         100 50 0.25  0.75  0.45
9         100 10 0.50  0.75  0.45
10        100 50 0.50  0.75  0.45
11        100 10 0.75  0.75  0.45
12        100 50 0.75  0.75  0.45
13        100 10 0.25  0.45  0.75
14        100 50 0.25  0.45  0.75
15        100 10 0.50  0.45  0.75
16        100 50 0.50  0.45  0.75
17        100 10 0.75  0.45  0.75
18        100 50 0.75  0.45  0.75
19        100 10 0.25  0.75  0.75
20        100 50 0.25  0.75  0.75
21        100 10 0.50  0.75  0.75
22        100 50 0.50  0.75  0.75
23        100 10 0.75  0.75  0.75
24        100 50 0.75  0.75  0.75

如何将每一行参数值传递到我的模型并自动运行 paramspace 中规定的所有参数化?

最佳答案

根据评论中的建议,您可以创建一个函数,然后使用 apply 循环参数组合:


## functions needed to run the model
learn <- function(prior, sensi, speci, e){
  out <- ifelse(e == 1, (sensi*prior) / ((sensi*prior) + (1-speci)*(1-prior)),
                ((1-sensi)*prior) / (((1-sensi)*prior) + (speci*(1-prior))))
  out
}

feed <- function(vec,sensi,speci){
  prior <- 0.5
  for (i in vec){
    res <- learn(prior, sensi, speci, i)
    prior <- res
  }
  return(prior)
}

runModel <- function(iterations = 100,
                     N = 10,
                     BR = 0.66,
                     sensi = 0.75,
                     speci = 0.45 ) {
  ## initialize results object
  res <- NULL
  
  ## loop for number of iterations
  for (j in 1:iterations){
    
    X <- as.numeric(rbinom(1, 1, BR))
    
    if (X == 1){ # if X is 1...
      agents <- c(1:N) 
      evidence <- vector("list", length(agents)) 
      for (i in agents) {
        n <- sample(10, 1, replace = TRUE) 
        evidence[[i]] <- rbinom(n, 1, sensi) 
      }
    } else { # if X is 0... 
      agents <- c(1:N)
      evidence <- vector("list", length(agents)) 
      for (i in agents) {
        n <- sample(10, 1, replace = TRUE) 
        evidence[[i]] <- rbinom(n, 1, sensi) 
        evidence[[i]] <- ifelse(evidence[[i]]==1, 0, 1) # flip evidence 
      }
    }
    
    # feed vectors of evidence through learn function
    #t0 <- sapply(evidence, feed)
    t0 <- sapply(evidence,function(e){feed(e,sensi,speci)})
    
    # save dataframe 
    df <- list("i" = iterations, 
               "ID" = c(1:N), 
               "E" = t0, 
               "X" = X,
               "N" = N, 
               "BR" = BR,
               "sensi" = sensi,
               "speci" = speci)
    
    res <- rbind(res, df)
    
  }
  res
}

# Define parameter space
iterations <- 100
N_vec <- c(10, 50)
BR_vec <- c(0.25, 0.50, 0.75) 
sensi_vec <- c(0.45, 0.75)
speci_vec <- c(0.45, 0.75)

paramspace <- expand.grid(iterations = iterations, N = N_vec, BR = BR_vec, sensi = sensi_vec, speci = speci_vec)

# Loop over parameter space :
res <- apply(paramspace,1,function(paramset) {
  iterations = paramset[1]
  N = paramset[2]
  BR = paramset[3]
  sensi = paramset[4]
  speci = paramset[5]
  runModel(iterations = iterations, N = N, BR = BR , sensi = sensi, speci = speci )
})

关于r - 如何在for循环中迭代参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62832732/

相关文章:

r - 计数具有共享元素的组

R Shiny - 在侧边栏面板外显示静态文本

batch-file - 批处理文件嵌套 For/L 循环并退出它们

pandas - 在Pandas数据框中查找值的索引

c - 这个递归的例子正确吗?

r - 独立于行构面的数量来控制ggplot2构面的高度

r - 使用 Likert 包在 R 中创建发散堆积条形图时出现问题

c - 为什么具有 int 字段 "forget"的结构类型在第一次 for 循环后它的值是什么?

Java For 循环数据验证

OpenCV:矩阵迭代