Как я могу запретить библиотеке маскировать функции

#r

#r

Вопрос:

Типичная ситуация следующая:

 library(dplyr)
library(xgboost)
 

Когда я импортирую библиотеку xgboost , функция slice dplyr маскируется, и мне приходится писать dplyr::slice , хотя я никогда не использую xgboost::slice явно.

Очевидное решение проблемы — импортировать xgboost раньше dplyr . Но безумно импортировать все библиотеки, которые могут повлиять на функции dplyr заранее. Более того, эта проблема часто возникает, когда я использую caret library. А именно train , функция автоматически импортирует требуемые библиотеки, и некоторые функции при этом маскируются.

  1. Можно ли предотвратить маскировку некоторых функций?
  2. Можно ли замаскировать «функцию маскирования» (например xgboost::slice ) с помощью ранней импортированной функции (например dplyr::slice )?

Примечания

  • Я НЕ спрашиваю, как отключить предупреждающее сообщение.
  • Я НЕ спрашиваю, как использовать маскируемые функции.

Комментарии:

1. Вы спрашиваете, как обойти критический способ, которым R обрабатывает пространства имен (и, крича, не меньше). Один из способов, который заставляет вас выполнять некоторую работу (amp;, я понимаю трудности, связанные с вводом 7 дополнительных символов для использования замаскированной функции или даже настройкой ярлыка в вашей IDE для dslice<TAB> dplyr::slice автоматического включения), но вы также можете создать pkg, который выполняет импорт pkg, а затем экспортирует функции изэто, что было бы неплохо, если бы вы в конечном итоге использовали одни и те же комбинации или R source -скрипт в начале без 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:

  1. Можно ли предотвратить маскировку некоторых функций?

Я в это не верю, но я могу ошибаться. Я не уверен, как это будет выглядеть

  1. Можно ли замаскировать «функцию маскирования» (например, 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!