Цикл в моделировании набора данных - PullRequest
0 голосов
/ 13 мая 2019

Я надеюсь получить справку по следующей проблеме в R.

У меня есть следующий код для генерации набора данных из 30 столбцов на основе экспоненциального распределения:

x0=0
xmax=8000
xout=3000
lambda=0.0002
n=1

  x1=x0+rexp(n,lambda)-xout
  x2=x1+rexp(n,lambda)-xout
  x3=x2+rexp(n,lambda)-xout
  x4=x3+rexp(n,lambda)-xout
  x5=x4+rexp(n,lambda)-xout
  x6=x5+rexp(n,lambda)-xout
  x7=x6+rexp(n,lambda)-xout
  x8=x7+rexp(n,lambda)-xout
  x9=x8+rexp(n,lambda)-xout
  x10=x9+rexp(n,lambda)-xout
  x11=x10+rexp(n,lambda)-xout
  x12=x11+rexp(n,lambda)-xout
  x13=x12+rexp(n,lambda)-xout
  x14=x13+rexp(n,lambda)-xout
  x15=x14+rexp(n,lambda)-xout
  x16=x15+rexp(n,lambda)-xout
  x17=x16+rexp(n,lambda)-xout
  x18=x17+rexp(n,lambda)-xout
  x19=x18+rexp(n,lambda)-xout
  x20=x19+rexp(n,lambda)-xout
  x21=x20+rexp(n,lambda)-xout
  x22=x21+rexp(n,lambda)-xout
  x23=x22+rexp(n,lambda)-xout
  x24=x23+rexp(n,lambda)-xout
  x25=x24+rexp(n,lambda)-xout
  x26=x25+rexp(n,lambda)-xout
  x27=x26+rexp(n,lambda)-xout
  x28=x27+rexp(n,lambda)-xout
  x29=x28+rexp(n,lambda)-xout
  x30=x29+rexp(n,lambda)-xout

У меня три сомнения:

1 - Можно ли написать эту функцию в сокращенном виде?

2 - Эту строку (30 столбцов) необходимо смоделировать 10000 раз.Как это сделать в цикле?

3 - Значения каждой ячейки (x1, x2, x3 ...) должны быть ограничены интервалом x0 и xmax (0-8000).Как это сделать?

Ответы [ 3 ]

2 голосов
/ 13 мая 2019

Это зависит от того, что вы хотите сделать со значениями свыше 8000. Вот решение, которое просто берет эти значения и оборачивает их с помощью оператора по модулю.

library(tidyverse)

test <- data.frame(x0 = rep(0, n))
for (i in 1:30) {
  new_col <- sym(paste0("x", i))
  old_col <- sym(paste0("x", i - 1))
  test <- test %>% 
    mutate(!!new_col := (!!old_col + rexp(n, lambda) - xout) %% xmax)
}

Я не знаю, насколько вы знакомы или не знакомы с оценкой приведения в порядок и опрятности, которую я здесь широко использовал. Оператор !! в сочетании с sym() превращает имена переменных в реальные переменные. Оператор %>% передает данные от одной функции к другой. Оператор := необходим только в том случае, если вы хотите выполнять назначения с !! слева.

Я думаю, что я впервые пытаюсь опубликовать ответ в StackOverflow, так что будьте спокойны за меня! :)

1 голос
/ 13 мая 2019

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

xmax <- 8000
xout <- 3000
lambda <- 0.0002
n <- 1
iterations <- 30

df <- data.frame(matrix(ncol = 31, nrow = iterations))
names(df) <- c(paste("x", 0:30, sep=""))

for (j in 1:iterations) {
  df$x0[j] <- 0
  df$x1[j] <- df$x0[j] + rexp(n,lambda)-xout
  if (df$x1[j] < 0) {
    df$x1[j] <- 0
  }
  if (df$x1[j] > 8000) {
    df$x1[j] <- 8000
  }
  for (i in 3:31) {
    df[j,i] <- df[j, i-1] + rexp(n,lambda)-xout
    if (df[j,i] < 0) {
      df[j,i] <- 0
    }
    if (df[j,i] > 8000) {
      df[j,i] <- 8000
    }
  }
}

Вы можете изменить iterations на 30000, для целей тестирования я использовал 30.Также я не знал, хотите ли вы ограничить 0 и 8000 до или после следующих итераций, я делал это раньше.

1 голос
/ 13 мая 2019
  1. Есть ли способ написать эту функцию в сокращенном виде?

Я бы сделал это так.Уверен, это эквивалентно.

ncol = 30

row = rexp(ncol, lambda)
row = cumsum(row) - xout * (1:ncol)
Эту строку (30 столбцов) необходимо смоделировать 10000 раз.Как сделать это в цикле?

Используйте replicate с кодом выше:

sim_data = t(replicate(10000, {
  row = rexp(ncol, lambda)
  row = cumsum(row) - xout * (1:ncol)
}))

replicate дает 10000 столбцов и 30 строк.Мы используем t(), чтобы переместить его в 10000 строк с 30 столбцами.

Значения каждой ячейки (x1, x2, x3 ...) должны быть ограничены интервалом x0 и xmax (0-8000).Как это сделать?

Используйте pmin() и pmax().Не уверен, что вы хотите сделать это до или после накопительного суммирования ...

sim_data = t(replicate(10000, {
  row = rexp(ncol, lambda)
  row = cumsum(row) - xout * (1:ncol)
  row = pmax(0, row)
  row = pmin(xmax, row)
  row
}))
...