0

I am playing around with an agent-based model in R. I am trying to wrap my toy model in a function to allow me to easily run multiple models. Unfortunately, I cannot get my results out via a return function. I must be doing something silly. My toy model code looks like this:

#--------- start script ---------#

require(tidyverse)

agent_generator <- function(pop_size, init_exposed){
  # create population of susceptible agents
  agents <- data.frame(agent_no = 1:pop_size,
                       state = "s",
                       mixing = runif(pop_size, 0, 1),
                       stringsAsFactors = FALSE)
  agents$state[1:init_exposed] <- "e"
  return(agents)
}

simple_model <- function(agents, mix, steps){
  pop_size <- nrow(agents)
  
  # define data outputs
  edge_list <- data.frame()
  node_list <- data.frame()
  
  for(k in 1:steps){
    for(i in 1:pop_size){
      # likelihood of an agent to go out and meet others
      connect_with <- round(likelihood * mix, 0) + 1 
      
      # which agents will they probably meet (list of agents)
      meet_ups <- sample(1:pop_size, 
                         connect_with, 
                         replace = T, 
                         prob = agents$mixing)
      
      # create edge list
      df <- data.frame(agent = meet_ups)
      edges <- expand(df, from = agent, to = agent) %>%
        filter(from < to) %>%
        mutate(day = k) %>%
        arrange(day)
      
      edge_list <- bind_rows(edge_list, edges)
      
      for(j in 1:length(meet_ups)){
        contacts <- agents[meet_ups[j],]
        
        # if exposed, change state
        if(contacts$state == "e"){
          urand <- runif(1,0,1)
          
          # control probability of state change
          if(urand < 0.5){
            agents$state[i] <- "e"
          }
        }
        
        # create node list
        nodes <- agents %>%
          select(agent_no, state) %>%
          mutate(day = k + 1) %>%
          arrange(day)
        node_list <- bind_rows(node_list, nodes)
      } 
    }
  }
  return(edge_list)
  return(node_list)
}

agents <- agent_generator(20,5)
model_1 <- simple_model(agents, mix = 10, steps = 15)

#--------- end script ---------#

When I run the code outside a function, I get node_list and edge_list. My return function is not working. Can someone kindly show me the errors of my ways?

aterhorst
  • 625
  • 4
  • 14
  • 1
    R functions can only return one object. If you want to return 2 objects, put them in a list - `return(list(edges = edge_list, nodes = node_list))`. – Gregor Thomas Mar 23 '21 at 02:40
  • 1
    A function in R can only return one "value". That value could be a list of other values, but you can have at most one return statement in a function. Once a return statement is found, none of the rest of the code in the function will run. – MrFlick Mar 23 '21 at 02:40
  • Thanks. Using ```return(list(edges = edge_list, nodes = node_list))``` works. The next step is to create a network graph from edge_list and node_list. I can wrap that in a function as well. – aterhorst Mar 23 '21 at 02:51

0 Answers0