связывание вектора в R - PullRequest
       4

связывание вектора в R

4 голосов
/ 29 августа 2010

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

Имеет цикл for, программа генерирует вектор на каждой итерации. Мне нужно, чтобы каждый сгенерированный вектор добавлялся к существующему вектору.

Я не знаю, как это сделать в R. Спасибо за помощь.

Ответы [ 4 ]

7 голосов
/ 29 августа 2010

Эти ответы работают, но все они требуют вызова недетерминированной функции, такой как sample() в цикле.Это не инвариантный к циклу код (каждый раз он случайный), но он все равно может быть удален из цикла for.Хитрость заключается в том, чтобы использовать аргумент n и сгенерировать все случайные числа, которые вам нужны заранее (если ваша проблема это позволяет, некоторые могут нет, но многие это делают).Теперь вы делаете один звонок, а не n, что имеет значение, если ваш n большой.Вот быстрый пример случайного блуждания (но многие проблемы могут быть сформулированы таким образом).Кроме того, полное раскрытие: у меня не было любого кофе сегодня, поэтому, пожалуйста, укажите, если вы видите ошибку: -)

steps <- 30
n <- 100
directions <- c(-1, 1)

results <- vector('list', n)

for (i in seq_len(n)) {
  walk <- numeric(steps)
  for (s in seq_len(steps)) {
    walk[s] <- sample(directions, 1)
  }
  results[[i]] <- sum(walk)
}

Мы можем переписать это одним вызовом sample():

all.steps <- sample(directions, n*steps, replace=TRUE)
dim(all.steps) <- c(n, steps)
walks <- apply(all.steps, 1, sum)

Подтверждение увеличения скорости (n = 10000):

> system.time({
+ for (i in seq_len(n)) {
+   walk <- numeric(steps)
+   for (s in seq_len(steps)) {
+     walk[s] <- sample(directions, 1)
+   }
+   results[[i]] <- sum(walk)
+ }})
   user  system elapsed 
  4.231   0.332   4.758 

> system.time({
+ all.steps <- sample(directions, n*steps, replace=TRUE)
+ dim(all.steps) <- c(n, steps)
+ walks <- apply(all.steps, 1, sum)
+ })
   user  system elapsed 
  0.010   0.001   0.012 

Если для моделирования требуется только одна случайная величина на вызов функции моделирования, используйте sapply() илиеще лучше multicore пакет mclapply().Пакет Revolution Analytics foreach может также использоваться здесь.Кроме того, у JD Long есть отличная презентация и пост о симуляции вещей в R на Hadoop через EMR Amazon здесь (я не могу найти видео, но я уверен, что кто-то узнает).

Возьмите начальные очки:

  • Предварительно выделите с помощью numeric(n) или vector('list', n)
  • Выдвиньте инвариантный код из for циклов.Умело выталкивайте стохастические функции из кода с их аргументом n.
  • Старайтесь для sapply() или lapply(), или еще лучше mclapply.
  • Не используйте x <- c(x, rnorm(100)).Каждый раз, когда вы делаете это, член R-core убивает щенка.
2 голосов
/ 29 августа 2010

Вероятно, лучшее, что вы можете сделать, - это предварительно выделить список длины n (n - количество итераций) и выровнять список после того, как вы закончите.

n <- 10
start <- vector("list", n)
for (i in 1:n) {
  a[[i]] <- sample(10)
}
start <- unlist(start)

Ты мог бы сделать это по-старому. Это может быть медленно для больших векторов.

start <- c()
for (i in 1:n) {
  add <- sample(10)
  start <- c(start, add)
}
0 голосов
/ 29 августа 2010

Если ваша функция симуляции - назовите ее func - каждый раз возвращает вектор одинаковой длины, вы можете сохранить результаты в столбцах предварительно выделенной матрицы:

sim1 <- function(reps, func) {
  first <- func()
  result <- matrix(first, nrow=length(first), ncol=reps)
  for (i in seq.int(from=2, to=reps - 1)) {
    result[, i] <- func()
  }
  return(as.vector(result))
}

Или вы можете выразить это следующим образом, используя копию:

sim2 <- function(reps, func) {
  return(as.vector(replicate(reps, func(), simplify=TRUE)))
}

> sim2(3, function() 1:3)
[1] 1 2 3 1 2 3 1 2 3
0 голосов
/ 29 августа 2010
x <- rnorm(100)
for (i in 100) {
   x <- c(x, rnorm(100))
}

Эта ссылка должна быть полезной: http://www.milbo.users.sonic.net/ra/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...