R: Использование канала %>% и pkg::fo приводит к ошибке «Ошибка в .::базе : неиспользуемый аргумент»

#r #pipe #tidyverse #magrittr

#r #канал #tidyverse #magrittr

Вопрос:

Я использую magrittr канал %>%, за которым немедленно следует функция, вызываемая: package::function, и получаю ошибку: Ошибка в .::base : неиспользуемый аргумент (среднее значение)

В чем проблема?

 library(magrittr)
c(1,2) %>%
  base::mean
#> Error in .::base: unused argument (mean)
  

Ответ №1:

Что происходит, так это то, что magrittr запутывается в том, в какую именно функцию вы хотите вставить предыдущее значение. Когда вы делаете просто

 c(1,2) %>%
  mean
  

magrittr может легко увидеть, что mean это символ, указывающий на функцию mean . Но когда вы это делаете base::mean , все становится немного сложнее, потому что :: это также функция в R. Давайте сравним разницу между base::mean и base::mean() в R с точки зрения того, как они преобразуются в вызовы функций.

 as.list(quote(base::mean))
# [[1]]
# `::`    
# [[2]]
# base    
# [[3]]
# mean

as.list(quote(base::mean()))
#  [[1]]
# base::mean
  

Вы можете увидеть эти синтаксические анализы по-разному. Когда вы просто наберете base::mean R, сначала увидите :: функцию и попытаетесь ввести туда цифры. В основном to пытается вызвать

 `::`(., base, mean)
  

что не имеет смысла, может быть, это то, что выдает вам это конкретное сообщение об ошибке

Но если вы явно добавите () , R сможет увидеть, что вы пытаетесь вызвать функцию, возвращаемую из base::mean , поэтому она добавит параметр в нужное место. Итак, вы можете сделать

 c(1,2) %>%
  base::mean()
  

или

 c(1,2) %>%
    (base::mean)
  

Ответ №2:

Обратите внимание, что существует версия magrittr , в которой нет этой проблемы, но она уже очень давно не загружалась в CRAN.

Как описано в этой проблеме, github-версия magrittr pipes может успешно справляться с

 c(1,2) %>%
    base::mean
  
 [1] 1.5
  

Это было исправлено 4 года назад, но так и не попало в CRAN. Поскольку большинство людей будут использовать версию CRAN, я бы не советовал писать код, который зависит от этого исправления.

Ответ №3:

Оказывается, что если вы вызовете функцию с дополнительным аргументом, она не будет работать. Простое решение — использовать (.) , т.е. base::mean(.) :

 library(magrittr)
c(1,2) %>%
  base::mean(.)
#> [1] 1.5
  

Более подробно это объясняется в: magrittr и wrapr Pipes в R, проверка

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

1. Я думаю, вы можете просто сделать c(1,2) %>% mean

2. да, но это обман! В противном случае я мог бы также сделать mean(c(1,2)) 😉

3. хорошо, я думал, вы хотите использовать функцию конкретно в pipe

4. Этот ответ просто сбивает с толку. . Здесь не играет никакой роли. Magrittr может отменить то, что вы пытаетесь сделать, если вы просто выполните c(1,2) %>% base::mean()