Мышление в векторах с R - PullRequest
       24

Мышление в векторах с R

25 голосов
/ 13 января 2009

Я знаю, что 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 минут. Есть идеи почему?

Ответы [ 2 ]

8 голосов
/ 13 января 2009

Очевидно, что я должен был поработать над этим еще час, прежде чем опубликовать свой вопрос. Это так очевидно в ретроспективе. :)

Чтобы использовать векторную логику 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. </p>

Векторы в R удивительно быстрые для меня. Наверное, поэтому я экономист, а не ученый.

6 голосов
/ 14 января 2009

Чтобы ответить на ваш вопрос о том, почему цикл 10000 занял намного больше времени, чем цикл 1000:

Я думаю, что основным подозрением являются конкатенации, которые происходят в каждом цикле. Поскольку данные становятся длиннее, R, вероятно, копирует каждый элемент вектора в новый, более длинный. Быстрое копирование небольшого (в среднем 500 элементов) набора данных 1000 раз. Копирование большего (в среднем 5000 элементов) набора данных в 10000 раз медленнее.

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