Что такое надежный процесс отсоединения пакета R, чтобы его обновить?
Я написал пакет, который использует devtools для включения внутренних данных:
devtools::use_data(.data, internal = T, overwrite = T)
Недавно я изменил эти данные и перестроил пакет. Я хочу обновить этот пакет на другом компьютере, на котором загружен более старый пакет:
detach('package:myPackage', unload=T)
remove.packages('myPackage')
install.packages(repos=NULL, 'myPackage.zip')
Я проверяю, прошли ли изменения:
length(myPackage:::.data[[1]])
[1] 2169
Не то, что я ожидал... может быть, перезагрузка поможет?
Restarting R session...
length(myPackage:::.data[[1]])
[1] 2179
Каков ожидаемый результат.
Чтение справки для отсоединения говорит о том, что в некоторых случаях оно может быть неровным, например:
Если вы используете библиотеку в пакете, пространство имен которого загружено, оно привязывает экспорт уже загруженного пространства имен. Поэтому отсоединение и повторная установка пакета может не обновлять некоторые или все компоненты пакета и нецелесообразно.
Моя ситуация здесь заключается в том, что я хочу полностью очистить загруженный пакет, чтобы обновить его. Есть ли способ сделать это без перезапуска R?
EDIT 2016/10/28 - обновлено с воспроизводимым примером ниже
- проверено на windows
- требуется devtools
...
# setup package in temp dir
pkg_dir <- file.path(tempfile(), 'dummy.test.pkg')
dir.create(pkg_dir, recursive=T)
devtools::create(pkg_dir)
setwd(pkg_dir)
# read description
desc <- readChar('DESCRIPTION', file.size('DESCRIPTION'))
# create and build package v01
.testval <- c(1,2,3)
devtools::use_data(.testval, internal=T, overwrite=T)
v01 <- sub('\\d+\\.\\d+\\.\\d+\\.\\d+', '0.0.0.1', desc, perl=T)
writeChar(v01, 'DESCRIPTION')
bin01 <- devtools::build(binary=T, path='.')
# create and build package v10
.testval <- c(4,5,6)
devtools::use_data(.testval, internal=T, overwrite=T)
v01 <- sub('\\d+\\.\\d+\\.\\d+\\.\\d+', '1.0.0.0', desc, perl=T)
writeChar(v01, 'DESCRIPTION')
devtools::build(binary=T, path='.')
bin10 <- devtools::build(binary=T, path='.')
# up to this point we haven't loaded either package
sessionInfo()
# install v01
install.packages(repos=NULL, bin01)
cat(dummy.test.pkg:::.testval)
# 1 2 3 (as expected)
# unload the package
unloadNamespace('dummy.test.pkg')
# install v10
install.packages(repos=NULL, bin10)
cat(dummy.test.pkg:::.testval)
# 1 2 3 (NOT 4 5 6 which we expected)
### restart R here ###
cat(dummy.test.pkg:::.testval)
# 4 5 6 (as expected)
Ответы
Ответ 1
Вы ищете unloadNamespace
. Я использую его для конкретной цели, которую вы все время описываете.
Просто позвоните по порядку:
# this may fail, see below
unloadNamespace("mypackage")
# if it succeeds you're all good
# updating the package
install.packages("mypackage")
# reloading the updated package
library("mypackage")
У меня никогда не было проблем с этим, будь то установка из source/binary, из local/CRAN/github, с/без packrat и т.д.
EDIT: это не решает проблему OP, которая обновляет данные пакета. Однако он работает хорошо для большинства более простых случаев, например. обновляя некоторый R-код, поэтому я оставляю ответ для будущих читателей.
Однако может случиться так, что целевой пакет был фактически импортирован другими загруженными пакетами. В этом случае сбой не выполняется.
Например, я знаю, что это не сработает в моем текущем сеансе:
> unloadNamespace("magrittr")
Error in unloadNamespace("magrittr") :
namespace ‘magrittr’ is imported by ‘stringr’, ‘customFunctions’, ‘dplyr’, ‘tidyr’ so cannot be unloaded
Решение состоит в том, чтобы сначала выгрузить (с unloadNamespace
) все пакеты, импортирующие "mypackage".
Если есть много импортирующих пакетов, вы можете фактически сэкономить время, просто перезапустив R. (Поскольку вы, кажется, говорите о пользовательском локальном пакете, это, вероятно, не произойдет с вами, если вы не написали другие пакеты в зависимости от она.)
Ответ 2
Если вы не хотите перезапускать сеанс R, безопасным способом получения новых данных будет сохранение данных, например. на
save(.data, "data.rda")
скопируйте их на другую машину и там
load("data.rda")