Неэффективность циклов в R

Доброе утро,

Я разрабатывал в течение нескольких месяцев в R, и я должен удостовериться, что время выполнения моего кода не является слишком длинным, потому что я анализирую большие наборы данных.

Следовательно, я пытался использовать как можно больше векторизованные функции.

Однако я все еще задаюсь вопросом что-то.

То, что является дорогостоящим в R, не является самим циклом право? Я имею в виду, проблема возникает, когда Вы начинаете изменять переменные в цикле, например, это исправляет?

Следовательно я думал, что, если просто необходимо выполнить функцию на каждом элементе (Вы на самом деле не заботитесь о результате). Например, записать данные в базе данных. Что необходимо сделать?

1) использовать mapply, не храня результат нигде?

2) цикл по вектору и только применяют f (i) к каждому элементу?

3) существует ли лучшая функция, которую я, возможно, пропустил?

(это, конечно, предполагает, что Ваша функция оптимально не векторизована).

Что относительно foreach пакет? Вы испытали какое-либо повышение производительности при помощи его?

5
задан SRKX 29 June 2010 в 02:02
поделиться

1 ответ

Только пара комментариев. Цикл for примерно так же быстр, как apply и его варианты, а реальное увеличение скорости происходит, когда вы максимально векторизуете свою функцию (то есть используете низкоуровневые циклы, а не apply, который просто скрывает цикл for). Я не уверен, что это лучший пример, но рассмотрим следующий:

> n <- 1e06
> sinI <- rep(NA,n)
> system.time(for(i in 1:n) sinI[i] <- sin(i))
   user  system elapsed 
  3.316   0.000   3.358 
> system.time(sinI <- sapply(1:n,sin))
   user  system elapsed 
  5.217   0.016   5.311 
> system.time(sinI <- unlist(lapply(1:n,sin),
+       recursive = FALSE, use.names = FALSE))
   user  system elapsed 
  1.284   0.012   1.303 
> system.time(sinI <- sin(1:n))
   user  system elapsed 
  0.056   0.000   0.057 

В одном из комментариев ниже Марек указывает, что самая трудоемкая часть цикла for выше - это часть ]<-:

> system.time(sinI <- unlist(lapply(1:n,sin),
+       recursive = FALSE, use.names = FALSE))
   user  system elapsed 
  1.284   0.012   1.303 

Узкие места, которые не могут быть немедленно векторизованы, могут быть переписаны на C или Fortran, скомпилированы с помощью R CMD SHLIB, а затем подключены с помощью . Call, .C или .Fortran.

Также смотрите эти ссылки для получения дополнительной информации об оптимизации циклов в R. Также ознакомьтесь со статьей "Как избежать этого цикла или сделать его быстрее?" в R News.

6
ответ дан 13 December 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: