Подтвердить что ты не робот

Мышление в векторах с 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 минут. Любая идея почему?

4b9b3361

Ответ 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 раз медленнее.