тип/происхождение функции R 'as'

Объектно-ориентированная система R S3 сосредоточена вокруг универсальных функций, которые вызывают методы в зависимости от класса объекта, для которого вызывается универсальная функция. Суть в том, что универсальная функция вызывает соответствующий метод, в отличие от других языков программирования OO, в которых метод определяется внутри класса.

Например, функция mean является общей функцией.

isGeneric("mean")
methods(mean)

Это напечатает

TRUE
[1] mean,ANY-method          mean.Date                mean.default             mean.difftime           
[5] mean.IDate*              mean,Matrix-method       mean.POSIXct             mean.POSIXlt            
[9] mean,sparseMatrix-method mean,sparseVector-method
see '?methods' for accessing help and source code

Я немного изучал R и нашел функцию as. Меня смущает тот факт, что R говорит, что функция не является универсальной, но у нее все еще есть методы.

isGeneric("as")
methods(as)

TRUE
  [1] as.AAbin                                  as.AAbin.character                       
  [3] as.alignment                              as.allPerms                              
  [5] as.array                                  as.array.default                         
  [7] as.binary                                 as.bitsplits                             
  [9] as.bitsplits.prop.part                    as.call
  ...                                  

В конце есть предупреждение о том, что as не является дженериком.

 Warning message:
 In .S3methods(generic.function, class, parent.frame()) :
 function 'as' appears not to be S3 generic; found functions that look like S3 methods

Может ли кто-нибудь объяснить мне, что такое функция as и как она связана с as.list, as.data.frame и т. д.? R говорит, что as.list является универсальным (где у меня возникает соблазн немного разозлиться из-за несоответствий в R, потому что я ожидал, что as.list будет методом для объекта list из универсальной функции as). Пожалуйста помоги.


person PejoPhylo    schedule 14.01.2018    source источник
comment
From ?as, The S3 functions listed are those which are named like methods and may not actually be methods (known exceptions are discarded in the code). Если вы посмотрите на источник для as, он не похож на универсальный S3 (как mean) только с вызовом UseMethod, что подкрепляет утверждение, что это не универсальный. Однако это только часть истории; здесь определенно есть что рассказать.   -  person alistaire    schedule 14.01.2018
comment
Два несколько связанных вопроса с интересными обсуждениями в комментариях: as(x, 'double ') и as.double(x) несовместимы, Почему для целочисленного вектора x as(x, «numeric») запускает загрузку дополнительного метода S4 для принуждения?   -  person Henrik    schedule 14.01.2018
comment
К сожалению, приведенная выше цитата принадлежит ?methods, а не ?as.   -  person alistaire    schedule 14.01.2018


Ответы (1)


as не является общим для S3, но обратите внимание, что вы получили TRUE. (Я получил FALSE.) Это означает, что вы загрузили пакет, который определяетas как S4-универсальный. Обобщения S3 работают через диспетчеризацию классов, которая использует функцию *.default и функцию UseMethod. ЛОЖЬ, которую я получаю, означает, что для универсального as не определен метод, который можно было бы найти. Одной из возможных причин отсутствия общего as является то, что вызов такой функции только с одним объектом данных не указывал бы «назначение принуждения». Это означает, что пункт назначения должен быть встроен в имя функции.

После объявления as общим (обратите внимание на заглавные буквы, которые намекают на то, что это относится к функциям S4:

setGeneric("as")  # note that I didn't really even need to define any methods

get('as')
#--- output----
standardGeneric for "as" defined from package "methods"

function (object, Class, strict = TRUE, ext = possibleExtends(thisClass, 
    Class)) 
standardGeneric("as")
<environment: 0x7fb1ba501740>
Methods may be defined for arguments: object, Class, strict, ext
Use  showMethods("as")  for currently available ones.

Если я перезагружаю R (и не загружаю никакие библиотеки, которые вызывают setGeneric для «как»), я получаю:

get('as')
#--- output ---
function (object, Class, strict = TRUE, ext = possibleExtends(thisClass, 
    Class)) 
{
    if (.identC(Class, "double")) 
        Class <- "numeric"
    thisClass <- .class1(object)
    if (.identC(thisClass, Class) || .identC(Class, "ANY")) 
        return(object)
    where <- .classEnv(thisClass, mustFind = FALSE)
    coerceFun <- getGeneric("coerce", where = where)
    coerceMethods <- .getMethodsTable(coerceFun, environment(coerceFun), 
        inherited = TRUE)
    asMethod <- .quickCoerceSelect(thisClass, Class, coerceFun, 
        coerceMethods, where)
    .... trimmed the rest of the code

Но вы спрашиваете «почему», всегда опасный вопрос при обсуждении дизайна языка, конечно. Я просмотрел последнюю главу Статистических моделей в S, которая является цитируемой ссылкой для большинства справочных страниц, относящихся к диспетчеризации S3, и не нашел обсуждения ни принуждения, ни функции as. Существует неявное определение «универсального S3», требующее использования UseMethod, но не упоминается, почему as не учитывалось в этой стратегии. Я думаю о двух возможностях: это должно предотвратить любую двусмысленность наследования при применении принуждения или это эффективное решение.

Вероятно, я должен добавить, что существует S4-функция setAs и что вы можете найти все функции S4-принуждения с помощью showMethods("coerce").

person IRTFM    schedule 14.01.2018
comment
Здесь все еще остается открытым вопрос, почему функции принуждения, такие как as.character, названы как методы S3 для as, хотя они таковыми не являются (и не могут быть таковыми, поскольку они структурированы). Исторические причины, я уверен, но мне любопытны особенности того, как R оказался с таким вопиющим несоответствием. - person alistaire; 14.01.2018
comment
Я представил свои теории, но я думаю, что это действительно вопрос к авторам, и очень немногие из них часто повторяют ТАК. Возможно, запрос Rhelp был бы более информативным. - person IRTFM; 14.01.2018