0

I did check this problem but couldn't find an exact solution. Furthermore, applying the solution threw another error.

I did write the following function for agents' matchmaking.

    library(tidyverse)
    library(cowplot)
    library(gridExtra)
    library(grid)
    library(Rmisc)


    matchmaking_two_value <- function(eta_lt,eta_rt,rho_lt,rho_rt,theta,time,
                                  target = c("eta_lt","eta_rt","rho_lt","rho_rt")){
  
    storage_v2 <- matrix(NA_real_, nrow = time, ncol = 4)
    graphs <- list()
    storage_v2 <- as.data.frame(storage_v2)
    colnames(storage_v2) <- c("eta_lt","eta_rt","rho_lt","rho_rt")
  
    for (i in 1:time) {
    storage_v2[i,1] <- eta_lt
    storage_v2[i,2] <- eta_rt
    storage_v2[i,3] <- rho_lt
    storage_v2[i,4] <- rho_rt
    
    
    eta_lt_next <- (2*eta_rt*rho_lt) - (2*eta_lt*rho_rt) + (2*theta*eta_lt*eta_rt) - (2*(1-theta)*eta_rt*eta_lt) + eta_lt^2
    eta_rt_next <- 1 - eta_lt_next - rho_lt - rho_rt
    
    if(eta_lt_next <= 0) {
      eta_lt <- 0
      eta_rt <- 1 - (eta_lt + rho_lt + rho_rt)
    } else{
      eta_lt <- eta_lt_next
      eta_rt <- eta_rt_next
    }
 
 
    
 
     }
         plot <- storage_v2%>%ggplot(mapping = aes(x = 1:time)) + 
         geom_line(aes(y = eta_lt, color = "Eta_L")) + 
         geom_line(aes(y = eta_rt, color = "Eta_R")) + 
         geom_line(aes(y = rho_lt, color = "Rho_L")) + 
         geom_line(aes(y = rho_rt, color = "Rho_R")) + 
         
         ggtitle("Population", subtitle = paste("Theta: ", theta)) + 
         ylab("Proportions") + xlab("Time") + 
         scale_color_manual(name = "Agent Types", 
                            breaks = c("Eta_L","Eta_R","Rho_L","Rho_R"), 
                            values = c("Eta_L" = "khaki4","Eta_R" = "salmon3", 
                                       "Rho_L" = "darkslateblue", "Rho_R" = "tomato4")) + 
         theme_minimal()
  
  
    print(storage_v2)
    print(plot)

}

This function gives the results if I give the input. Although I want to use this function for creating multiple plots. Such as following

for(i in seq(0,0.9,0.1)){
matchmaking_two_value(eta_lt = i, eta_rt = 0.9-i, rho_lt= 0.05, rho_rt = 0.05, theta = 0.5, time = 10)
}

My problem is I can't store the function's results under the list. Any solution would be appreciated

6
  • 1
    Could you please better articulate you question in a clear, straightforward statement and provide sample data? This will likely get you good help faster. In the lower code, you aren't saving anything - have you tried list_data[[i]] <- matchmaking_two_value(...)`? Commented May 26, 2022 at 16:56
  • 1
    One reason you might not be able to save the function's results is that it doesn't return anything. Also, when all you do in the loop is assign a function's return value to an object and then only access the object outside the loop, you are likely to encounter lazy evaluation problems. Typically this is characterised by every element of ther array or list being assigned the same value - the value returned by the final evaluation of the loop. Far better to use a member of the apply family, all of which force evaluation. Commented May 26, 2022 at 17:00
  • @jpsmith Yes! Thank you for your instant reply. I did try to save it, as you mentioned. But it is just storing the last value, which is logical. I am trying to get these plots and plot them under one graphs with grid.extra. Commented May 26, 2022 at 17:31
  • @Limey I am sorry. I don't think I am advanced enough to understand what you mean. Which function can I use from the apply family to get the results of the graphs in the for loop as a list? Commented May 26, 2022 at 17:33
  • See, for example, here. Commented May 26, 2022 at 17:40

1 Answer 1

1

You need a function that actually returns a value. If you just print() results in the function, those side effects cannot be collected and used later. So change your function from

matchmaking_two_value <- function(...){
  ...
  print(storage_v2)
  print(plot)
}

to

matchmaking_two_value <- function(...){
  ...
  list(data=storage_v2, plot=plot)`
}

Then when you are return a list, you can collect those values in a list quickly with something like lapply()

result <- lapply(seq(0,0.9,0.1), function(i) {
  matchmaking_two_value(eta_lt = i, eta_rt = 0.9-i, rho_lt= 0.05, rho_rt = 0.05, theta = 0.5, time = 10)
})

Then you can extract the plots and data with commands like

result[[1]]$plot
result[[1]]$data
result[[10]]$plot
result[[10]]$data

To get a list of all the plots to send to grid.extra you can do

allplots <- lapply(result, function(x) x$plot)
gridExtra::grid.arrange(grobs=allplots)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.