Загрузить пакет r в выбранной среде
Я новичок в разработке пакетов R и переполнении стека, но мне нигде не удалось найти эту информацию.
Я пытаюсь загрузить мышь R пакета, не загрязняя мое пространство имен. Я пытался импортировать только те функции, которые я использую, но это не сработало. Поэтому я согласен на загрузку всего пакета в одной конкретной среде следующим образом:
e <- new.env()
load_package_into_environment(e, package = "mice")
eval(mice(data, m = m, maxit = max.iter, printFlag = F), envir = e)
Тем не менее, я не смог найти фактическую функцию для замены заполнителя "load_package_into_environment". Какая функция, если таковая имеется, будет выполнять это?
РЕДАКТИРОВАТЬ: Вот файлы, с которыми я работаю, и проблема, которую я должен дать более подробно.
Описание файла
Package: bug.example2
Title: Example of Package Loading Bug
Version: 0.0.0.9000
Authors@R: person("R", "Woodbridge", email = "example@gmail.com", role = c("aut", "cre"))
Description: Creates a wrapper function for mice::mice function.
Depends:
R (>= 3.2.3),
data.table (>= 1.9.6)
License:
LazyData: true
Imports: mice
RoxygenNote: 5.0.1
Файл: NAMSPACE (автоматически генерируется roxygen)
import(data.table)
importFrom(mice,mice)
importFrom(mice,mice.impute.logreg)
importFrom(mice,mice.impute.pmm)
importFrom(mice,mice.impute.polr)
importFrom(mice,mice.impute.polyreg)
Файл: impute.R (использует функцию мышей из пакета мышей)
#' @import data.table
#' @importFrom mice mice
#' @importFrom mice mice.impute.pmm
#' @importFrom mice mice.impute.logreg
#' @importFrom mice mice.impute.polyreg
#' @importFrom mice mice.impute.polr
#' @export
impute <- function(data, m = 5, max.iter = 5){
mice_environment <- new.env()
#Impute missing data using mice function, output format is mids object
mice.out <- mice(data, m = m, maxit = max.iter, printFlag = F)
#save the m imputed data.frames as a list of data.tables
return.list <- lapply(1:m, function(x){
as.data.table(complete(mice.out, x))
})
names(return.list) <- paste0("imp.",1:m)
return.list
}
Файл: test-impute.R (использует пакет testthat для проверки функции вменения)
context("Impute missing values")
test_that("Output format is a list of lenght m and each element is a data.table",{
#Set up data
set.seed(200)
data <- iris
data$Species[runif(nrow(data)) < .1] <- NA
data$Sepal.Width[runif(nrow(data)) < .2] <- NA
setDT(data)
#Create imputed data
M <- 5
impute.output <- impute(data, m = M)
#Test output format
expect_is(impute.output, "list")
expect_equal(length(impute.output), M)
lapply(impute.output,expect_is, "data.table")
})
Ошибка вывода из testthat
1. Error: Output format is a list of lenght m and each element is a data.table -
The following functions were not found: mice.impute.pmm, mice.impute.polyreg
1: withCallingHandlers(eval(code, new_test_environment), error = capture_calls, message = function(c) invokeRestart("muffleMessage"))
2: eval(code, new_test_environment)
3: eval(expr, envir, enclos)
4: impute(data, m = M) at test-impute.R:12
5: mice(data, m = m, maxit = max.iter, printFlag = F) at C:\repos\bug.example2/R/impute.R:11
6: check.method(setup, data)
7: stop(paste("The following functions were not found:", paste(fullNames[notFound],
collapse = ", ")))
2 ответа
Пакет "Мышь" внутренне вызывает методы вменения из глобальной среды. По мнению авторов, это позволяет предоставить собственные, собственные методы для вменения. Таким образом, пакет должен также предоставлять свои реализации по умолчанию в глобальной среде. Я считаю, что это хороший пример чистого суждения - внутренние методы теперь распознаются пакетом только через глобальную среду. Это побеждает цель упаковки кода в первую очередь. Если кто-то хочет разрешить использование внешних функций вашим пакетом, просто предоставьте API для передачи их в пакет.
Сообщение об ошибке, которое вы видите, вызывается функцией 'mice:::check_method':
notFound <- !vapply(fullNames, exists, logical(1), mode = "function", inherits = TRUE)
Мой обходной путь - реэкспорт методов, используемых внутренне "мышами", из моего собственного пакета (который внутренне использует "мышей", как и у вас). Просто вставьте один из ваших файлов R и запустите на нем roxygen2:
#' @importFrom mice mice
#' @export
mice.impute.pmm <- mice::mice.impute.pmm
#' @export
mice.impute.polyreg <- mice::mice.impute.polyreg
Конечно, вам нужно экспортировать другие методы, если они используются в ваших данных.
Моя точка зрения заключается в том, что если мне нужно загрязнять глобальную окружающую среду, я буду загрязнять ее минимально, только с помощью функций, необходимых для работы "мышей".
Вчера я получил ту же ошибку и открыл аналогичный вопрос (кстати, это уже было отклонено). Сегодня я нашел решение, я надеюсь, что оно работает и для вас, и, возможно, вы (или другие) можете пролить немного света на него.
Я разрабатываю пакет R и использую roxygen2 для документирования функций. Я перечислил мышей в разделе импорта в файле описания, так как я должен использовать функцию mice::mice. При сборке и проверке пакета все работает без сбоев, пока я фактически не запустил функцию, которая вызывает mice::mice, в этот момент я получаю ту же ошибку, что и вы.
Насколько я понимаю, именно это и вызывает проблему: в части документации функции, которая использует мышь, вам нужно добавить этот бит:
#' @importMethodsFrom mice
#' @importFrom mice mice
Обратите внимание, что с большинством пакетов, которые я использовал до сих пор, следующей строки было бы более чем достаточно:
#' @importFrom mice mice
Очевидно, для мышей требуется, чтобы вы также добавили директиву @importMethodsFrom. Я предполагаю, что это потому, что он использует классы S4, но я мало знаю о них, поэтому я просто знаю, что так оно и работает.
Я узнал об этом, прочитав раздел "S4" на этой странице: http://r-pkgs.had.co.nz/namespace.html
Итак, чтобы вернуться к вашему конкретному случаю, я предполагаю, что документы для вашей функции должны выглядеть примерно так
#' @import data.table
#' @importFrom mice mice
#' @importMethodsFrom mice
#' @export
impute <- function(data, m = 5, max.iter = 5){...}
Это работало нормально для меня. Надеюсь, это поможет и вам.