18 março, 2021

Introdução

  • Nas aulas anteriores, discutimos sobre atribuição e escopo
  • Estes estão relacionados com o objeto ambiente, de modo environment
    • Definição: nome <- valor

Ambiente

  • Similar a uma lista, porém:
    • Cada nome deve ser único;
    • Os nomes em um ambiente não são ordenados;
    • Um ambiente tem um pai ou também chamado de ambiente superior;
    • Ambientes não são copiados quando modificados.

Alguns tipos de ambientes

  • Ambiente global: .GlobalEnv ou globalenv()
  • Ambiente Corrente: environment()
  • Ambiente Vazio: emptyenv()
  • Ambiente base: ambiente de pacote e de namespace, baseenv()
  • Ambiente namespace
  • Ambiente de pacote
  • Ambientes funcionais

Nomes em um ambiente

> # Nomes no ambiente global
> ls()
## character(0)
> # Criando objetos no ambiente global
> b <- 2; a <- "Ben"; x <- TRUE
> # Verificando os nomes no ambiente global
> ls()
## [1] "a" "b" "x"

Acessando objetos em ambiente

> # Acessando o objeto "a"
> .GlobalEnv$a
## [1] "Ben"
> .GlobalEnv[["a"]]
## [1] "Ben"
> # Acessando o primeiro nome (Erro...)
> .GlobalEnv[[1]]
## Error in .GlobalEnv[[1]]: argumentos errados para obtenção de subconjuntos de um ambiente

Criando ambientes

> # Criando objetos no ambiente global
> b <- 2; a <- "Ben"; x <- TRUE
> ls() # Verificando os nomes no ambiente global
## [1] "a" "b" "x"
> # Criando um objeto ambiente no ambiente global
> amb1 <- new.env()
> # Inserindo nomes nesse no ambiente "amb1"
> amb1$d <- 3; amb1$e <- "FALSE"
> ls() # Verificando nomes no ambiente global
## [1] "a"    "amb1" "b"    "x"
> ls(envir = amb1) # Verificando nomes no ambiente "amb1"
## [1] "d" "e"

Ambiente pai

  • Pai de amb1
> parent.env(amb1)
## <environment: R_GlobalEnv>
  • Pai do ambiente vazio
> parent.env(emptyenv())
## Error in parent.env(emptyenv()): o ambiente vazio não tem pai

Ambientes funcionais e superatribuição

Vamos falar apenas de dois: ambiente envolvente e ambiente de execução

> x <- 0 # Criando o objeto x e o imprimindo
> # Criando uma funcao com a superatribuicao
> f1 <-  function() {
+   # Obj2
+   x <- 1
+   # Modificando x do ambiente global
+   x <<- 2
+   # Imprimindo o ambiente de execucao
+   env <- environment()
+   # Imprimindo o Obj2
+   res <- list(x = x, "Ambiente de execução" = env, "Ambiente Pai" = parent.env(env))
+   # Retornando a lista
+   return(res)
+ }

Ambientes funcionais

> f1() # Imprimindo f1
## $x
## [1] 1
## 
## $`Ambiente de execução`
## <environment: 0x0000000006ab3780>
## 
## $`Ambiente Pai`
## <environment: R_GlobalEnv>
> x # Imprimindo x
## [1] 2
> environment(f1) # Imprimindo o ambiente envolvente de f1
## <environment: R_GlobalEnv>

Ambientes funcionais

> ls() # Imprimindo os nomes do ambiente global
## [1] "a"    "amb1" "b"    "f1"   "x"

Novo começo no ambiente de execução

> f1()$`Ambiente de execução`
## <environment: 0x000000000901b698>
> f1()$`Ambiente de execução`
## <environment: 0x00000000083938a8>
> f1()$`Ambiente de execução`
## <environment: 0x000000000830f6c0>

Superatribuição

> # Verificando os nomes no ambiente global
> ls()
## character(0)
> # Criando uma funcao
> f2 <-  function() {
+   x <<- 2
+ }
> # Executando f2
> f2()
> # Verificando novamente os nomes no ambiente global
> ls(); x
## [1] "f2" "x"
## [1] 2

Superatribuição

> # Funcao contador
> contador <- function() {
+   i <- 0
+   env1 <- environment()
+   aux <- function() {
+     # do something useful, then ...
+     i <<- i + 1
+     env2 <- environment()
+     res2 <- list(i = i, `AmbExec_aux` = env2, `AmbExec_contador` = env1)
+     return(res2)
+   }
+ }

Superatribuição e ambiente de execução

> # Chamada de funcao
> contador1 <- contador(); contador1(); contador1()
## $i
## [1] 1
## 
## $AmbExec_aux
## <environment: 0x0000000007485978>
## 
## $AmbExec_contador
## <environment: 0x00000000075f1a18>
## $i
## [1] 2
## 
## $AmbExec_aux
## <environment: 0x00000000072abc20>
## 
## $AmbExec_contador
## <environment: 0x00000000075f1a18>

Superatribuição e ambiente de execução

> # Chamada de funcao
> contador2 <- contador()
> contador2()
## $i
## [1] 1
## 
## $AmbExec_aux
## <environment: 0x0000000008e88958>
## 
## $AmbExec_contador
## <environment: 0x000000000748f1b8>

Caminho de busca

> # Caminho de busca
> search()
##  [1] ".GlobalEnv"        "package:magrittr"  "package:stats"    
##  [4] "package:graphics"  "package:grDevices" "package:utils"    
##  [7] "package:datasets"  "package:methods"   "Autoloads"        
## [10] "package:base"
> # Anexando o pacote SMR
> library(SMR)

Caminho de busca

> # Verificando o caminho de busca
> search()
##  [1] ".GlobalEnv"        "package:SMR"       "package:magrittr" 
##  [4] "package:stats"     "package:graphics"  "package:grDevices"
##  [7] "package:utils"     "package:datasets"  "package:methods"  
## [10] "Autoloads"         "package:base"
> # Carregando o pacote midrangeMCP
> library(midrangeMCP)
> # Verificando o caminho de busca
> search()
##  [1] ".GlobalEnv"          "package:midrangeMCP" "package:SMR"        
##  [4] "package:magrittr"    "package:stats"       "package:graphics"   
##  [7] "package:grDevices"   "package:utils"       "package:datasets"   
## [10] "package:methods"     "Autoloads"           "package:base"

Hierarquia no caminho de busca

> # Criando um ambiente
> amb2 <- new.env()
> # Verificando seus parentais
> rlang::env_parents(env = amb2, last = emptyenv())
##  [[1]] $ <env: global>
##  [[2]] $ <env: package:midrangeMCP>
##  [[3]] $ <env: package:SMR>
##  [[4]] $ <env: package:magrittr>
##  [[5]] $ <env: package:stats>
##  [[6]] $ <env: package:graphics>
##  [[7]] $ <env: package:grDevices>
##  [[8]] $ <env: package:utils>
##  [[9]] $ <env: package:datasets>
## [[10]] $ <env: package:methods>
## [[11]] $ <env: Autoloads>
## [[12]] $ <env: package:base>
## [[13]] $ <env: empty>

Pesquisa pelo caminho de busca

> # Criando uma funcao
> f3 <- function() x + 1
> 
> # Modificando o ambiente envolvente de f3
> environment(f3) <- emptyenv()
> 
> # Dependencias externas da funcao f3
> codetools::findGlobals(f3)
## [1] "+" "x"
> # Chamando a funcao f3
> f3()
## Error in x + 1: não foi possível encontrar a função "+"

Cuidado com a função attach()

> # objeto quadro de dados
> dados <- data.frame(sd = 1:3, var = (1:3)^2)
> # Caminho de busca
> search()
##  [1] ".GlobalEnv"          "package:midrangeMCP" "package:SMR"        
##  [4] "package:magrittr"    "package:stats"       "package:graphics"   
##  [7] "package:grDevices"   "package:utils"       "package:datasets"   
## [10] "package:methods"     "Autoloads"           "package:base"
> # anexando "dados" ao caminho de busca
> attach(dados)
> # Verificando novamente o caminho de busca
> search()
##  [1] ".GlobalEnv"          "dados"               "package:midrangeMCP"
##  [4] "package:SMR"         "package:magrittr"    "package:stats"      
##  [7] "package:graphics"    "package:grDevices"   "package:utils"      
## [10] "package:datasets"    "package:methods"     "Autoloads"          
## [13] "package:base"

Cuidado com a função attach()

> # Imprimindo sd
> sd
## [1] 1 2 3
> # Desanexando "dados"
> detach(dados)
> # Imprimindo sd
> sd
## function (x, na.rm = FALSE) 
## sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x), 
##     na.rm = na.rm))
## <bytecode: 0x0000000008dfb620>
## <environment: namespace:stats>

Bons estudos!