#r
#r
Вопрос:
Типичная ситуация следующая:
library(dplyr)
library(xgboost)
Когда я импортирую библиотеку xgboost
, функция slice
dplyr
маскируется, и мне приходится писать dplyr::slice
, хотя я никогда не использую xgboost::slice
явно.
Очевидное решение проблемы — импортировать xgboost
раньше dplyr
. Но безумно импортировать все библиотеки, которые могут повлиять на функции dplyr
заранее. Более того, эта проблема часто возникает, когда я использую caret
library. А именно train
, функция автоматически импортирует требуемые библиотеки, и некоторые функции при этом маскируются.
- Можно ли предотвратить маскировку некоторых функций?
- Можно ли замаскировать «функцию маскирования» (например
xgboost::slice
) с помощью ранней импортированной функции (напримерdplyr::slice
)?
Примечания
- Я НЕ спрашиваю, как отключить предупреждающее сообщение.
- Я НЕ спрашиваю, как использовать маскируемые функции.
Комментарии:
1. Вы спрашиваете, как обойти критический способ, которым R обрабатывает пространства имен (и, крича, не меньше). Один из способов, который заставляет вас выполнять некоторую работу (amp;, я понимаю трудности, связанные с вводом 7 дополнительных символов для использования замаскированной функции или даже настройкой ярлыка в вашей IDE для
dslice<TAB>
dplyr::slice
автоматического включения), но вы также можете создать pkg, который выполняет импорт pkg, а затем экспортирует функции изэто, что было бы неплохо, если бы вы в конечном итоге использовали одни и те же комбинации или Rsource
-скрипт в начале безfunction_name <- pkg::function_name
него, чтобы он переопределял2. Я помню, что был одним из многих людей, которые отвечали на этот вопрос около 6 месяцев назад. Там должен быть существующий ответ, если вы его ищете. Мы придумали множество творческих решений. В любом случае, не могли бы вы, пожалуйста, объяснить мне это: «безумно импортировать все библиотеки, которые могут повлиять на функции dplyr заранее» . Почему это безумие? В любом случае вы должны импортировать все свои библиотеки в начале своего кода (например, C, Java и т. Д. И т. Д.) В качестве наилучшей практики, И вы можете просто поставить
dplyr
last .3. @Hack-R Если вы ответили на этот вопрос, вам может быть проще найти дубликат и предложить его в качестве дубликата.
4. Я нахожу ситуацию немного более тревожной, чем @hrbmstr (эй, это нарушает старый код; В интерактивных сеансах, где люди используют dplyr и т. Д., префикс в два раза сложнее), А также меньше ошибок, чем Hack-R: включите вопросы порядка, и вы не защищены от существующих пакетовдобавление функций сглаживания. Предлагаемое изменение (см. Мой Ответ Ниже) потенциально действительно полезно.
5. Мне очень жаль, что я не упомянул, что я спрашиваю об интерактивном сеансе. Если мы пишем сценарий, который выполняется в оболочке, то мы должны импортировать необходимые библиотеки в начале сценария. Но я никогда не думаю, что тот же способ должен применяться к интерактивному сеансу.
Ответ №1:
Следующая версия R содержит это в файле NEWS {.Rd} (цитируется из файла NEWS
после сборки):
• The import() namespace directive now accepts an argument except
which names symbols to exclude from the imports. The except
expression should evaluate to a character vector (after
substituting symbols for strings). See Writing R Extensions.
Здесь приведен ссылочный текст из руководства (в формате raw texi).
Так скоро мы сможем. Прямо сейчас это невозможно, и это огромная боль в заднице, особенно когда маскируются функции из базовых пакетов R: lag()
, filter()
, …
В прошлом мы использовали термин «антисоциальный» для такого поведения. Я не думаю, что это слишком сильно.
Чтобы проиллюстрировать проблему, вот фрагмент кода, который я написал десять лет назад (и опубликовал его в ныне исчезнувшей галерее R Graph), в котором используется умный и быстрый способ вычисления скользящего среднего:
## create a (normalised, but that's just candy) weight vector
weights <- rep(1/ndays, ndays)
## and apply it as a one-sided moving average calculations, see help(filter)
bbmiddle <- as.vector(filter(dat$Close, weights,
method="convolution", side=1))
Если вы будете делать library(dplyr)
то, что могли бы в интерактивном сеансе, вы окажетесь в тупике, поскольку filter()
сейчас это нечто совершенно другое. Нехорошо.
Ответ №2:
- Можно ли предотвратить маскировку некоторых функций?
Я в это не верю, но я могу ошибаться. Я не уверен, как это будет выглядеть
- Можно ли замаскировать «функцию маскирования» (например, xgboost:: slice) с помощью ранней импортированной функции (например, dplyr::slice)?
Если вы спрашиваете о just или use в интерактивном сеансе, вы всегда можете просто определить slice
функцию, которую вы на самом деле хотите использовать, например
slice <- dplyr::slice
и затем вы можете использовать slice
, как если бы это была версия dplyr (потому что теперь это так).
Комментарии:
1. В настоящее время нет, но «скоро» скоро в R 3.4.0 следующей весной. Или R-devel сейчас, если вам не все равно. Смотрите ответ, который я только что опубликовал.
Ответ №3:
Решение состоит в том, чтобы управлять вашим пространством имен, как это обычно делается на других языках. Вы можете выборочно импортировать функции dplyr:
select <- dplyr::select
Для удобства вы также можете импортировать весь пакет и выборочно повторно импортировать функции из ранее подключенных пакетов:
library("dplyr")
filter <- stats::filter
R имеет отличную модульную систему, и присоединение целых пространств имен особенно удобно для интерактивного использования. Это требует небольшой ручной настройки, если предпочтения авторов пакета не совпадают с вашими.
Обратите внимание, что в пакетах и сценариях долгосрочного обслуживания вы должны использовать выборочный импорт, отчасти потому, что трудно предсказать новые экспортируемые функции в будущих выпусках. Массовый импорт нескольких пакетов может привести к неожиданному маскированию с течением времени.
В более общем плане хорошим правилом является полагаться на один подключенный пакет и выборочно импортировать остальные. С этой целью tidyverse
пакет может быть удобен, если вы являетесь активным пользователем tidyverse, поскольку он предоставляет единую точку импорта для нескольких пакетов.
Наконец, из вашего вопроса следует, что вы считаете, что порядок подключенных пакетов может иметь побочные эффекты внутри других пакетов. Об этом не о чем беспокоиться, потому что все пакеты имеют свои собственные контексты. Схема импорта повлияет только на ваш скрипт.
Ответ №4:
Теперь вы также можете использовать conflict_prefer()
функцию из conflicted
пакета, чтобы указать, какая функция пакета должна «выиграть», а какая должна быть замаскирована при наличии конфликтующих имен функций (подробности здесь). В вашем примере вы бы выполнили
conflict_prefer("slice", "dplyr", "xgboost")
сразу после загрузки ваших библиотек. Затем при запуске slice
по умолчанию будет использоваться dplyr::slice
значение using, а не xgboost::slice
. Или вы можете просто запустить
conflict_prefer("slice", "dplyr")
если вы хотите предоставить dplyr::slice
приоритет над функциями всех других пакетов. slice
Ответ №5:
Я знаю, что это глупый ответ, и этот поток очень старый (но у меня была такая же проблема только сегодня): Я изменил последовательность загрузки пакетов. Лично у меня возникли проблемы с функцией MASS и Dplyr «select». Я хотел бы всегда использовать версию Dplyr. Итак, сначала я загрузил MASS!