rfor-loopuser-defined-functionssocial-network-friendship

User defined function within for-loops


I am working on a project in which I am simulating 8 classroom social networks over 6 weeks, so 30 iterations. Students will nominate each other based on a number of factors, and I plan to simulate a number of conditions in which I remove or add some of these factors to the simulation. In other words, I'm going to be repeating a lot of code, so I'd rather use functions rather than cutting and pasting where ever possible.

Right now, I'm trying to create a function that adjusts the probability of one student selecting another based on the similarity of their emotions. When I include it in a set of nested for for loops, this works just fine:

num_students <- 5
names_students <- letters[1:num_students]
student_emotion <- sample(round(runif(5, min = -5, max = 5), digits = 1))
student_emotion_df <- cbind.data.frame(names_students, student_emotion)

probs <- rep(1/num_students, 5)
row_prob <- vector(length = 5)

for(i in 1:num_students){
  for(q in 1:num_students){
    if(abs(student_emotion[i]-student_emotion[q]) >= 0 &
       abs(student_emotion[i]-student_emotion[q]) <= .5){ 
      row_prob[q] <- 1*probs[q] 
    } else if(abs(student_emotion[i]-student_emotion[q]) > .5 &
              abs(student_emotion[i]-student_emotion[q]) <= 1) {
      row_prob[q] <- .75 * probs[q] 
    }
    else {
      row_prob[q] <- .5 * probs[q]
    } 
  } 
}

The row_prob object is a vector of probabilities a student i, in the column, will select student q, in the rows.

I've created a user-defined function based on the same code, and that works:

emotion_difference_fun <- function(probs){
  
  for(q in 1:num_students){
    if(abs(student_emotion[i]-student_emotion[q]) >= 0 &
       abs(student_emotion[i]-student_emotion[q]) <= .5){ 
      row_prob[q] <- 1*probs[q] 
    } else if(abs(student_emotion[i]-student_emotion[q]) > .5 &
              abs(student_emotion[i]-student_emotion[q]) <= 1) {
      row_prob[q] <- .75 * probs[q] 
    }
    else {
      row_prob[q] <- .5 * probs[q]
    } 
  }
  return(row_prob)
}

emotion_difference_fun(probs)

But when I try to embed that function within the for loop iterating through the columns, row_prob returns as an empty vector:

for(i in 1:num_students){
  
  emotion_difference_fun(probs)
  
}

Any thoughts on how I can get this to work?

Thanks for any help you're able to offer.


Solution

  • If I understood your question properly, then you need to assign the results in your last 'for' loop:

    for(i in 1:num_students){
            if(i == 1) out <- NULL
            out <- c(out, emotion_difference_fun(probs))   
    }
    out
    

    Is that what you are looking for?

    What I am unclear about though, is why in your second code section you are not looking for a 5*5 matrix. Eventually, when running that code, it doesn't matter that you did it for i = 5 students, because it will only save in row_prob your last iteration (student = 5).