Пользовательская функция в циклах for

Я работаю над проектом, в котором я моделирую 8 социальных сетей в классе в течение 6 недель, то есть 30 итераций. Студенты будут номинировать друг друга на основе ряда факторов, и я планирую смоделировать ряд условий, в которых я уберу или добавлю некоторые из этих факторов в симуляцию. Другими словами, я буду повторять много кода, поэтому я предпочитаю использовать функции, а не копировать и вставлять их там, где это возможно.

Прямо сейчас я пытаюсь создать функцию, которая регулирует вероятность того, что один ученик выберет другого на основе схожести их эмоций. Когда я включаю его в набор вложенных циклов for, это работает просто отлично:

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]
    } 
  } 
}

Объект row_prob представляет собой вектор вероятностей того, что студент i в столбце выберет студента q в строках.

Я создал определяемую пользователем функцию на основе того же кода, и она работает:

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)

Но когда я пытаюсь внедрить эту функцию в цикл for, перебирающий столбцы, row_prob возвращает пустой вектор:

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

Любые мысли о том, как я могу заставить это работать?

Спасибо за любую помощь, которую вы можете предложить.


person Gary DeYoung    schedule 05.02.2021    source источник


Ответы (2)


Если я правильно понял ваш вопрос, вам нужно присвоить результаты в последнем цикле for:

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

Это то, что вы ищете?

Однако мне непонятно, почему во втором разделе кода вы не ищете матрицу 5 * 5. В конце концов, при запуске этого кода не имеет значения, что вы сделали это для i = 5 студентов, потому что он сохранит только в row_prob вашу последнюю итерацию (student = 5).

person Rosalie Bruel    schedule 05.02.2021
comment
Кроме того, я не заметил вашего другого вопроса раньше. я представляет столбец и q строку. Итак, каждый студент i выбирает определенное количество студентов q на основе их эмоционального сходства или различия. Это всего лишь минимальный пример, но в полном коде я создаю вектор вероятностей для каждого студента i, и на его основе выбирается определенное количество студентов q. Вероятности выбора студентов и тех, кого выбрали, вставляются в матрицу столбец за столбцом, поэтому все сохраняется. Я знаю, что это, вероятно, не самое ясное, но это работает, когда я запускаю полный код :) - person Gary DeYoung; 06.02.2021

Вы можете использовать replicate, чтобы повторить функцию emotion_difference_fun для num_students.

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

Вы также можете установить simplify = FALSE для вывода в виде списка.

result <- replicate(num_students, emotion_difference_fun(probs),simplify = FALSE)
person Ronak Shah    schedule 06.02.2021
comment
Спасибо, Ронак. Я пробовал это, но он просто создает массив с одинаковыми результатами, повторяющимися пять раз. На самом деле должно быть 25 разных результатов. Я неправильно понимаю? - person Gary DeYoung; 06.02.2021
comment
Это потому, что каждый раз, когда вы запускаете emotion_difference_fun(probs), он возвращает один и тот же результат. Разве он не должен возвращать разные результаты? - person Ronak Shah; 07.02.2021
comment
Нет, на самом деле я хочу, чтобы это действовало как петля, чтобы вычислялась разница в эмоциях учеников А и В, А и В, А и Г.... Таким образом, должно быть 25 результатов, но они не должны повторять пять, которые я вычисляю с помощью функции. - person Gary DeYoung; 07.02.2021