R: путаница с apply () против цикла - PullRequest
3 голосов
/ 03 октября 2011

Я знаю, что мне следует избегать циклов for, но я не совсем уверен, как делать то, что я хочу, с помощью функции apply.

Вот несколько упрощенная модель того, что я пытаюсь сделать.Итак, по сути, у меня есть большая матрица предикторов, и я хочу запустить регрессию, используя окно из 5 предикторов на каждой стороне индексированного предиктора (i в случае цикла for).С помощью цикла for я могу просто сказать что-то вроде:

results<-NULL
window<-5
for(i in 1:ncol(g))
{
    first<-i-window #Set window boundaries
    if(first<1){
        1->first
    }
    last<-i+window-1
    if(last>ncol(g)){
        ncol(g)->last
    }
    predictors<-g[,first:last]

    #Do regression stuff and return some result
    results[i]<-regression stuff
}

Есть ли хороший способ сделать это с помощью функции apply?Моя проблема в том, что применяемый вектор будет влиять на функцию, и это не имеет значения.Все, что имеет значение, это индекс.

Ответы [ 2 ]

9 голосов
/ 03 октября 2011

Этот вопрос касается нескольких пунктов, которые сделаны в 'The R Inferno' http://www.burns -stat.com / pages / Tutor / R_inferno.pdf

Есть несколько циклов, которые вы должныизбегать, но не все из них.А использование функции применения больше скрывает цикл, чем его избегает.Этот пример кажется хорошим выбором, чтобы оставить его в цикле «for».

Растущие объекты, как правило, плохая форма - в некоторых случаях это может быть крайне неэффективно.Если у вас будет общее правило, то «не растущие объекты» лучше, чем «избегать петель».

Вы можете создать список с окончательной длиной:

result <- vector("list", ncol(g))
for(i in 1:ncol(g)) {
    # stuff
    result[[i]] <- #results
}

В некоторых случаях вы можете подумать, что команда:

window<-5

означает, что дайте мне логический вектор, указывающий, какие значения 'окна' меньше -5.

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

4 голосов
/ 03 октября 2011

Использование функции apply для регрессии в этом случае в основном является вопросом предпочтения;он может обрабатывать некоторые бухгалтерии для вас (и, возможно, предотвращать ошибки), но не ускоряет код.

Я бы предложил использовать векторизованные функции для вычисления ваших first и lastОднако, возможно, что-то вроде:

window <- 5
ng <- 15 #or ncol(g)
xy <- data.frame(first = pmax( (1:ng) - window, 1 ), 
                  last = pmin( (1:ng) + window, ng) )

Или быть еще умнее с

xy <- data.frame(first= c(rep(1, window), 1:(ng-window) ), 
                 last = c((window+1):ng, rep(ng, window)) )

Тогда вы можете использовать это в цикле for, например:

results <- list()
for(i in 1:nrow(xy)) {
  results[[i]] <- xy$first[i] : xy$last[i]
}
results

или с lapply, например:

results <- lapply(1:nrow(xy), function(i) {
  xy$first[i] : xy$last[i]
})

, где в обоих случаях я просто возвращаю последовательность между first и list;Вы должны заменить свой реальный код регрессии.

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