Как инициализировать библиотеки по их строковым именам в кластере?

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

Этот код работает нормально:

library(snowfall, rlecuyer, rsprng)
sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
sfClusterEval(library(e1071))

И этот код выдает ошибку: 4 nodes produced errors; first error: object 'expr' not found

library(snowfall, rlecuyer, rsprng)
sfInit(parallel = TRUE, cpus = 4, type = "SOCK")
lib <- "e1071"
expr <- parse(text=paste("library(", lib, ")", sep=""))
sfClusterEval(expr)

Итак, sfClusterEval попробуйте вычислить expr, а не выражение, которое содержит expr. Я не могу понять, какой тип выражения должен быть передан в функцию sfClusterEval, которая использует substitute в своем теле

> sfClusterEval
function (expr, stopOnError = TRUE) 
{
    sfCheck()
    if (sfParallel()) {
        return(sfClusterCall(eval, substitute(expr), env = globalenv(), 
            stopOnError = stopOnError))
    }
    else {
        return(eval(expr, envir = globalenv(), enclos = parent.frame()))
    }
}

Этот вопрос кажется простым, но я не смог его решить и нуждаюсь в чьем-то совете.

ОБНОВЛЕНИЕ:

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

sfClusterEval(library("e1071"))

Но этот вызов выдает en error: 4 узла выдали ошибки; первая ошибка: объект 'lib' не найден

lib <- "e1071"
sfClusterEval(library(lib, character.only=TRUE))

ОТВЕТ:

Переменная lib должна быть предварительно экспортирована в кластер. И после этого его можно удалить.

lib <- "e1071"
sfExport("lib")
sfClusterEval(library(lib, character.only=TRUE))
sfRemove("lib")

Спасибо за Ричи, за то, что дал стартовую идею!


person DrDom    schedule 03.02.2012    source источник
comment
Почему бы вам не использовать sfLibrary для загрузки пакетов в воркеры?   -  person Roman Luštrik    schedule 03.02.2012
comment
Отличный совет! Я пропустил эту функцию пакета snowfall. Мне стыдно. :) Если вы опубликуете этот комментарий как ответ, я смогу отметить его как решение.   -  person DrDom    schedule 05.02.2012


Ответы (2)


Вы можете использовать sfLibrary для загрузки дополнительных пакетов на рабочих. См. ?snowfall и нажмите snowfall-tools.

person Roman Luštrik    schedule 05.02.2012

Будь то в кластере или нет, вы просто используете аргумент character.only для library.

library("e1071", character.only = TRUE)

Если ваши узлы сообщают об ошибке, в которой говорится, что они не могут найти пакет, дважды проверьте, установлен ли пакет на этом компьютере в месте, которое является одним из .libPaths(). Если ничего не помогает, явно укажите расположение пакета в аргументе lib.loc для library.

person Richie Cotton    schedule 03.02.2012
comment
Хм... Похоже, в данной ситуации такой подход не работает. Смотрите обновление к ответу. Где я не прав? - person DrDom; 03.02.2012
comment
@DrDom: Обновлено, как найти пакет. - person Richie Cotton; 03.02.2012
comment
Это было еще проще, переменная lib отсутствовала в узлах кластера и поэтому была для них невидима. И я так понимаю оценка функции производится на каждом узле отдельно. Да, это логично, я знаю. Но тем не менее, большое Вам спасибо за правильное направление! - person DrDom; 03.02.2012
comment
Рад, что вы решили это. Если ответ был вам полезен, не забудьте нажать стрелку вверх, чтобы проголосовать. - person Richie Cotton; 03.02.2012
comment
Вы также можете рассмотреть возможность переноса своего решения на его собственный ответ (вы можете ответить на свой собственный вопрос), а затем щелкнуть галочкой, чтобы пометить его как решенное. - person Richie Cotton; 03.02.2012