19 agosto, 2021

Selo DC

Revisando

Método S3

  • Função tipo closure
  • Sintaxe: generic.class()
    • generic: nome da função genérica
    • class: nome da classe

Exemplo de método

# Funcao generica (ou generico)
quem <- function(x) UseMethod("quem")
# Objeto
pessoa <- "ben"
# Atribuindo classe ao objeto 'pessoa'
class(pessoa) <- "eh"
## Metodo
quem.eh <- function(x) print("Sou eu!")

Aspectos gerais de um método

  • Um método deve ser criado considerando a existência de uma função genérica ou uma classe;
  • O método deve apresentar os mesmos argumentos que a função genérica, excessão com '...';
  • Reforçando, evitem nos nomes das funções genéricas ou classes o uso de pontos;
  • A chamada de função deve ser realizada, preferencialmente pela função genérica;
  • Na criação de funções genéricas em pacotes, deem preferências ao nome das classes exatamente igual ao nome do pacote;

Chamada de função pelo “genérico” e não pelo método

Método padrão (default)

# Objeto
pessoa <- "ben"
# Atribuindo classe ao objeto 'pessoa'
class(pessoa) <- "eh"
## Metodo 'eh'
quem.eh <- function(x) print("Sou eu!")
## Metodo 'padrao'
quem.default <- function(x, y) print("??")
#-----------------------------------------
# Aplicacao:
pessoa <- "ben" # objeto sem atributo 'class'
# Usando a funcao generica
quem(pessoa) # Aplicando o metodo padrao
## [1] "??"
#--------
class(pessoa) <- "eh"
quem(pessoa) # Aplicando o metodo eh
## [1] "Sou eu!"

Retornando a características de UseMethod()

  • UseMethod: argumento object e omissão do método padrão
# Funcao generica
quem <- function(y) UseMethod("quem", x)
# Metodos
quem.eh <- function(y) print("Sou eu!")
quem.outro <- function(y) print("Outro!")
quem.default <- function(y) print("Qualquer um!")
# Objeto em UseMethod sem o atributo 'class'
x <- "ben"
# Objeto no primeiro argument de fgenerica
y <- "ninguem"
class(y) <- "outro"
# O despacho ocorre em quem.default
quem(y)
## [1] "Qualquer um!"

Retornando a características de UseMethod()

  • UseMethod: argumento object e omissão do método padrão
# Funcao generica
quem <- function(y) UseMethod("quem", x)
# Metodos
quem.eh <- function(y) print("Sou eu!")
quem.outro <- function(y) print("Outro!")
quem.default <- function(y) print("Qualquer um!")
# Objeto em UseMethod sem o atributo 'class'
x <- "ben"
# Objeto no primeiro argument de fgenerica
y <- "ninguem"
class(y) <- "outro"
# Removendo quem.defaul, a fgenerica retorna erro
rm("quem.default"); quem(y)
## Error in UseMethod("quem", x): método não aplicável para 'quem' aplicado a um objeto de classe "character"

Retornando a características de UseMethod()

  • UseMethod() foge do padrão das chamadas de função no R
# Funcao (Primeiro caso)
h <- function(x, y) {
  x <- 10
  y <- 10
  c(x = x, y = y)
}
x <- 1
y <- 1
h(x, y)
##  x  y 
## 10 10

Retornando a características de UseMethod()

  • UseMethod() foge do padrão das chamadas de função no R
# Funcao generica e metodo (Segundo caso)
g <- function(x, y) {
  x <- 10
  y <- 10
  UseMethod("g")
}
# metodo padrao
g.default <- function(x, y) c(x = x, y = y)
# Avaliacao
x <- 1
y <- 1
g(x, y)
## x y 
## 1 1

Retornando a características de UseMethod()

  • UseMethod() foge do padrão das chamadas de função no R
# Funcao generica e metodo (Terceiro caso)
g <- function(x) {
  x <- 10
  y <- 10
  UseMethod("g")
}
# metodo padrao
g.default <- function(x) c(x = x, y = y)
# Avaliacao
x <- 1
y <- 1
g(x)
##  x  y 
##  1 10

Retornando a características de UseMethod()

  • UseMethod() foge do padrão das chamadas de função no R
# Funcao generica e metodo (Quarto caso)
g.default <- function(x) c(x = x, y = y)
# Avaliacao
x <- 1
y <- 1
g.default(x)
## x y 
## 1 1

Criação de método por meio de funções primitivas genéricas

  • Usando a função print como exemplo
# Objeto classe 'comp'
x <- 1:10; class(x) <- "comp"
# Metodo 'comp'
print.comp <- function(x) {
  x <- unclass(x)
  cat("O comprimento de ", x, " eh ", length(x))
}
# Aplicacao
print(x) # Metodo 'comp'
## O comprimento de  1 2 3 4 5 6 7 8 9 10  eh  10
print(unclass(x)) # Metodo 'defaut'
##  [1]  1  2  3  4  5  6  7  8  9 10

Procurando por métodos

  • Funções utilizadas:
    • utils::methods()
    • sloop::s3_methods_generic()
    • sloop::s3_methods_class()

Procurando por métodos baseado no “genérico”

# Usando o nome da funcao generica
# utils::methods(print) 
##  [1] print.acf*                        
##  [2] print.AES*                        
##  [3] print.all_vars*                   
##  [4] print.anova*                      
##  [5] print.ansi_string*                
##  [6] print.ansi_style* 
##  ...
# Usando agora a funcao s3_methods_generic
sloop::s3_methods_generic("print")[1:6,]
## # A tibble: 6 x 4
##   generic class   visible source             
##   <chr>   <chr>   <lgl>   <chr>              
## 1 print   acf     FALSE   registered S3method
## 2 print   AES     FALSE   registered S3method
## 3 print   anova   FALSE   registered S3method
## 4 print   aov     FALSE   registered S3method
## 5 print   aovlist FALSE   registered S3method
## 6 print   ar      FALSE   registered S3method

Procurando por métodos baseados em uma classe

# Usando o nome da funcao generica
utils::methods(class = factor) # Imprimindo os primeiros metodos para a classe 'factor'
##  [1] [             [[            [[<-          [<-           all.equal    
##  [6] as.character  as.data.frame as.Date       as.list       as.logical   
## [11] as.POSIXlt    as.vector     c             coerce        droplevels   
## [16] format        initialize    is.na<-       length<-      levels<-     
## [21] Math          Ops           plot          print         relevel      
## [26] relist        rep           show          slotsFromS3   summary      
## [31] Summary       xtfrm        
## see '?methods' for accessing help and source code

Procurando por métodos baseados em uma classe

# Usando agora a funcao s3_methods_generic
sloop::s3_methods_class("factor")
## # A tibble: 28 x 4
##    generic       class  visible source
##    <chr>         <chr>  <lgl>   <chr> 
##  1 [             factor TRUE    base  
##  2 [[            factor TRUE    base  
##  3 [[<-          factor TRUE    base  
##  4 [<-           factor TRUE    base  
##  5 all.equal     factor TRUE    base  
##  6 as.character  factor TRUE    base  
##  7 as.data.frame factor TRUE    base  
##  8 as.Date       factor TRUE    base  
##  9 as.list       factor TRUE    base  
## 10 as.logical    factor TRUE    base  
## # ... with 18 more rows

Bons estudos!

Referências