Gary DeYoung
Gary DeYoung

Reputation: 106

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.

Upvotes: 0

Views: 601

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388807

You can use replicate to repeat the function emotion_difference_fun for num_students.

result <- replicate(num_students, emotion_difference_fun(probs))

You can also set simplify = FALSE to get output as list.

result <- replicate(num_students, emotion_difference_fun(probs),simplify = FALSE)

Upvotes: 0

Rosalie Bruel
Rosalie Bruel

Reputation: 1493

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).

Upvotes: 1

Related Questions