Как l oop через значения параметров, запустить функцию и сохранить результаты - PullRequest
0 голосов
/ 06 февраля 2020

Я записал симуляцию в функцию, чтобы я мог вручную устанавливать значения параметров и многократно запускать симуляцию с этими значениями параметров. Чтобы увидеть, как различные настройки влияют на результаты моего моделирования, я вручную изменил значения параметров, запустил моделирование и сохранил результаты. Я делаю это неоднократно и связываю вместе выходные данные для анализа / визуализации, но было бы намного удобнее, если бы я мог автоматизировать этот процесс.

Как я могу l oop через значения параметров, запустить симуляцию и сохранить все результаты в одном кадре данных?


Вот смысл моего кода выглядит так:

#### load libraries ####

library(plyr)
library(igraph)

#### set parameters N and StDv ####

N <- 10 

StDv <- 0.1

#### my model to be simulated, written as a function ####
myModel <- function(){

  #generate small world network, netSim, for the agents
  netSim <- sample_smallworld(dim = 1, nei = 1, size = N, p = 0.1) 

  #retrieve an adjacency matrix from net
  adjMatrix <- as.matrix(as_adjacency_matrix(netSim, names = TRUE, edges = FALSE)) 

  #create dataframe with numbered agents and assigned prior  
  data <- data.frame("agent" = c(1:N),
                     "t0" = rnorm(N, mean = 0.5, sd = StDv))

  #simulate communication and in the network for 5 rounds

  #round 1
  data$t1 <- with(data, ifelse(rowSums(adjMatrix) > 0,  
                               0.75 * t0 + (1-0.75) * (adjMatrix %*% t0 / rowSums(adjMatrix)), 
                               t0)) 

  #round 2
  data$t2 <- with(data, ifelse(rowSums(adjMatrix) > 0,  
                               0.75 * t1 + (1-0.75) * (adjMatrix %*% t1 / rowSums(adjMatrix)), 
                               t1)) 

  #round 3
  data$t3 <- with(data, ifelse(rowSums(adjMatrix) > 0,  
                               0.75 * t2 + (1-0.75) * (adjMatrix %*% t2 / rowSums(adjMatrix)), 
                               t2)) 

  #round 4
  data$t4 <- with(data, ifelse(rowSums(adjMatrix) > 0, 
                               0.75 * t3 + (1-0.75) * (adjMatrix %*% t3 / rowSums(adjMatrix)), 
                               t3)) 

  #round 5
  data$t5 <- with(data, ifelse(rowSums(adjMatrix) > 0,  
                               0.75 * t4 + (1-0.75) * (adjMatrix %*% t4 / rowSums(adjMatrix)), 
                               t4)) 


  #calculate measures of interest
  colResponses <- colMeans(data[2:7])
  colErrorSq <- (colResponses-1)^2
  variance <- as.vector(sapply(data[2:7], function(i)
    var(i)))
  data2 <- data[2:7] 
  data2 <- (data2-1)^2
  avgIndErrSq <- colMeans(data2)
  rm(data2)

  #bind together output 
  Output <- data.frame("N" = N,
                       "StDv" = StDv,
                       "Time" = c("t0", "t1", "t2", "t3", "t4", "t5"),
                       "Collective.Response" = colResponses,
                       "Collective.Error.Squared" = colErrorSq,
                       "Variance" = variance,
                       "Avg.Ind.Error.Squared" = avgIndErrSq)

}

#### Simulate my model by running the function 100 times and saving the results as "myResults" ####
myResults <- ldply(1:100, function(i) data.frame(Iteration = i, myModel())) 

У меня есть все N значения, которые я хочу исследовать в векторе: N_values <- c(10, 20, 40, 80)

И все StDv значения, которые я хочу исследовать в векторе: StDv_values <- c(0.05, 0.1, 0.25, 0.5)

Есть ли способ для l oop через каждую комбинацию N и StDv, запустить симуляцию и сохранить результаты в одном кадре данных?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Я бы написал вспомогательную функцию, чтобы позаботиться о повторяющихся деталях вызова myModel с соответствующими комбинациями значений.

runAll <- function(N_vec, StDv_vec){
  f <- function(N, StDv){
    ldply(1:100, function(i) data.frame(Iteration = i, myModel(N, StDv)))
  }
  vals <- expand.grid(N = N_vec, StDv = StDv_vec)
  res <- Map(function(.N, .StDv){f(.N, .StDv)}, vals$N, vals$StDv)
  res <- do.call(rbind, res)
  row.names(res) <- NULL
  res
}

N_values <- c(10, 20, 40, 80)
StDv_values <- c(0.05, 0.1, 0.25, 0.5)

res <- runAll(N_values, StDv_values)

dim(res)
#[1] 9600    8

Но это работает только в том случае, если функция myModel переопределена так, чтобы принимать два аргумента, N и StDv. Тело функции остается точно таким же.

myModel <- function(N, StDv){
  [...]
}
1 голос
/ 06 февраля 2020

Я бы предложил для l oop перебрать ваши варианты. Вложенный для l oop должен циклически перебирать все значения и комбинации для этих векторов.

#Loop through all N values in vector
for (i in 1:length(N_values)) {

    N = N_values[i]

    #Loop through all StDev values in vector for each 
    #iteration of all N values
    for (j in 1:length(StDv_values) {

        StDv = StDv_values[j]

        MyModel <- insert your model here... etc...
    }
}

Если можно ... Где у вас есть #bind together output и код:

Output <- data.frame("N" = N,
                 "StDv" = StDv,
                 "Time" = c("t0", "t1", "t2", "t3", "t4", "t5"),
                 "Collective.Response" = colResponses,
                 "Collective.Error.Squared" = colErrorSq,
                 "Variance" = variance,
                 "Avg.Ind.Error.Squared" = avgIndErrSq)

Вы создаете фрейм данных, но я не вижу, чтобы это было связано с чем-либо.

Для компиляции всех ваших данных я бы предложил что-то вроде следующего:

1 ) инициализируйте переменную NULL вне циклов for 2) Вставьте все новые значения Output data.frame в переменную CompiledDF для каждой итерации.

CompiledDF = NULL

#Loop through all N values in vector
for (i in 1:length(N_values)) {

    N = N_values[i]

    #Loop through all StDev values in vector for each 
    #iteration of all N values
    for (j in 1:length(StDv_values) {

        StDv = StDv_values[j]

        MyModel <- insert your model here... etc...


        Output <- data.frame(etc...
                                   )

        CompiledDF <- rbind(CompiledDF, Output)


    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...