2017-02-17 2 views
0

Я немного новичок с R, но у меня есть опыт работы с другими языками, такими как Python.Пока цикл внутри функции для R

Хотя я знаю, что есть пакеты, которые могут делать то, что я пытаюсь сделать для меня, я хочу по-настоящему понять этот язык программирования. Я пытаюсь создать симуляцию очереди M/M/1 и решил, что цикл while будет работать. Тем не менее, я немного застрял и надеюсь получить помощь.

# M/M/1 queue simulator 

lambda <- 2   # arrival rate 
mu <- 3    # service rate 
duration <- 10000 # total T of the simulation 
t <- 0    # current time in the simulation 
queue <- 0   # start with empty queue 
s <- 0    # running sum for computing average queue length 

# first arrival to start process 

T1 <- rexp(1,rate=lambda) 
currentqueue <- 1 
eventsTime <- T1 
t <- T1 
nEvents <- 1  # total number of events that have occurred 


sims <- function(lambda, mu, duration, t, queue, s) 
{ 
    while (t<duration) { 
     nEvents <- nEvents+1 
     if(currentqueue>0) { 
      T1 <- rexp(1,rate=lambda+mu) 

     p <- runif(1,0,1) 
     queue[nEvents] <- currentqueue 
     currentqueue <- ifelse(p<lambda/(lambda+mu), 
          currentqueue+1, 
          currentqueue-1) 
    } else { 
     T1 <- rexp(1,rate=lambda) 
     queue[nEvents] <- currentqueue 
     currentqueue <- 1 
    } 
    t <- t+T1 
    eventsTime[nEvents] <- T1 
    s <- s+T1*queue[nEvents] 
    } 
} 

sims(2,3,10000,0,0,0) #tests the function with given parameters 

Цикла в то время как сам по себе работает нормально и имитирует М/М/1 очередь, когда дано параметры лямбды, мю, длительность, т, очередь, и с. Из симуляции генерируется большое количество данных и помещается в eventsTime. Однако, когда я пытаюсь поместить это в:

sims <- function(lambda, mu, duration, t, queue, s) {} 

У меня проблема. Функция сохраняется - когда я проверяю «симы», она находится прямо там. Тем не менее, параметры теста, которые я вставляю, не выплевывают никакие смоделированные данные, несмотря на то, что R Studio явно выполняет некоторые вычисления.

Любые советы?

+1

Обычно в R мы не записываем функции таким образом, чтобы иметь побочные эффекты. т.е. мы не записываем функции, которые изменяют переменные _outside_ функции, что вы пытаетесь сделать. В результате ваша функция 'sims' явно не возвращает никаких значений, и все, что вы делаете внутри функции, только изменяет значения внутри области действия функции, а не где-либо еще. Возможно, вам стоит прочитать некоторые базовые руководства по написанию функций в R, которые охватывали бы эту концепцию. – joran

ответ

1

Функция sims явно не возвращает значение, поэтому возвращаемое значение является последним рассчитанным значением. (Такое поведение имеет смысл, так как функция, подобная функции (x) x^3, должна возвращать x кубик, когда это возможно.) В случае симов это значение является значением цикла while, а while - NULL.

> x <- 0 
> a <- while(x < 100) x <- x + 1 
> a 
NULL 

В результате симы всегда будет возвращать NULL:

> sims.demo <- function() { x <- 0 ; while(x < 100) x <- x + 1 } 
> a <- sims.demo() 
> a 
NULL 

Возвращение eventsTime и я думаю, что вы получите то, что вы хотите.

+0

Что делать, если я хотел многократно моделировать очередь, чтобы получить множество разных значений событий? С самого начала я этого не делал, поэтому извиняюсь. – wewtwewt

+0

Вы заполняете этот массив в конце цикла while, поэтому его возврат даст вам значения eventTime. Если вам нужно много массивов eventTime, зацикливайте симы. – JWLM

+0

Для справки, код, который вы написали, будет иметь ужасную производительность. R - копирование при записи, поэтому каждый раз, когда вы добавляете новое значение с назначением 'eventsTime [nEvents]', вы копируете весь массив 'eventsTime'. Вы бы намного лучше использовали собственный итератор, как sapply или vapply. – JWLM

Смежные вопросы