Мышление в векторах с R
Я знаю, что R работает наиболее эффективно с векторами, и циклов следует избегать. Мне трудно научиться писать код таким образом. Я хотел бы получить некоторые идеи о том, как "векторизовать" мой код. Здесь приведен пример создания 10-летней выборки данных для 10000 неповторимых комбинаций состояния (st
), plan1 (p1
) и plan2 (p2
):
st<-NULL
p1<-NULL
p2<-NULL
year<-NULL
i<-0
starttime <- Sys.time()
while (i<10000) {
for (years in seq(1991,2000)) {
st<-c(st,sample(c(12,17,24),1,prob=c(20,30,50)))
p1<-c(p1,sample(c(12,17,24),1,prob=c(20,30,50)))
p2<-c(p2,sample(c(12,17,24),1,prob=c(20,30,50)))
year <-c(year,years)
}
i<-i+1
}
Sys.time() - starttime
Это займет около 8 минут для работы на моем ноутбуке. В итоге я получаю 4 вектора, каждый из которых имеет 100 000 значений, как и ожидалось. Как это сделать быстрее с помощью векторных функций?
В качестве побочного примечания, если я ограничу вышеуказанный код 1000 петлями на i, он занимает всего 2 секунды, но 10 000 занимает 8 минут. Любая идея почему?
Ответы
Ответ 1
Ясно, что я должен был поработать над этим еще час, прежде чем я разместил свой вопрос. Это так очевидно в ретроспективе.:)
Чтобы использовать векторную логику R, я вынул цикл и заменил его следующим:
st <- sample(c(12,17,24),10000,prob=c(20,30,50),replace=TRUE)
p1 <- sample(c(12,17,24),10000,prob=c(20,30,50),replace=TRUE)
p2 <- sample(c(12,17,24),10000,prob=c(20,30,50),replace=TRUE)
year <- rep(1991:2000,1000)
Теперь я могу сделать 100 000 образцов почти мгновенно. Я знал, что векторы бывают быстрее, но денг. Я предполагаю, что 100 000 циклов заняли бы час, используя петлю, и векторный подход займет < 1 секунду. Просто для ударов я сделал векторы миллионным. Потребовалось ~ 2 секунды. Так как я должен протестировать сбой, я попробовал 10мм, но на моем 2Гб ноутбуке закончилась память. Я переключился на свой рабочий стол Vista 64 с 6 ГБ оперативной памяти и создал векторы длиной 10 мм за 17 секунд. 100-миллиметровые вещи развалились, так как один из векторов был более 763 мб, что привело к проблеме выделения с R.
Векторы в R удивительно быстры для меня. Думаю, почему я экономист, а не компьютерный ученый.
Ответ 2
Чтобы ответить на вопрос о том, почему цикл 10000 занял намного больше, чем ваш цикл из 1000:
Я думаю, что основным подозреваемым являются конкатенации, которые происходят в каждом цикле. По мере того как данные становятся длиннее, R, вероятно, копирует каждый элемент вектора в новый вектор, который является одним дольше. Копирование небольшого (500 элементов в среднем) набора данных в 1000 раз выполняется быстро. Копирование большего (5000 элементов в среднем) набора данных 10000 раз медленнее.