R Básico | Aula 23

Ambientes e caminho de busca

Encarte

Filosofia de publicação (Selo DC)

Apoio CEAC e UFSJ

Livro de Apoio

Usaremos Batista e Oliveira (2022):

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: 0x6160cd01b6d0>

$`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: 0x6160cd543518>
> f1()$`Ambiente de execução`
<environment: 0x6160cd6d2570>
> f1()$`Ambiente de execução`
<environment: 0x6160cd7254e0>

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: 0x6160ce0ef068>

$AmbExec_contador
<environment: 0x6160ce0cbf80>
$i
[1] 2

$AmbExec_aux
<environment: 0x6160ce1207a8>

$AmbExec_contador
<environment: 0x6160ce0cbf80>

Superatribuição e ambiente de execução

> # Chamada de funcao
> contador2 <- contador()
> contador2()
$i
[1] 1

$AmbExec_aux
<environment: 0x6160ce566a68>

$AmbExec_contador
<environment: 0x6160ce333158>

Caminho de busca

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

Caminho de busca

> # Verificando o caminho de busca
> search()
 [1] ".GlobalEnv"        "package:SMR"       "package:stats"    
 [4] "package:graphics"  "package:grDevices" "package:utils"    
 [7] "package:datasets"  "package:methods"   "Autoloads"        
[10] "package:base"     
> # Carregando o pacote midrangeMCP
> library(midrangeMCP)
> # Verificando o caminho de busca
> search()
 [1] ".GlobalEnv"          "package:midrangeMCP" "package:SMR"        
 [4] "package:stats"       "package:graphics"    "package:grDevices"  
 [7] "package:utils"       "package:datasets"    "package:methods"    
[10] "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:stats>
 [[5]] $ <env: package:graphics>
 [[6]] $ <env: package:grDevices>
 [[7]] $ <env: package:utils>
 [[8]] $ <env: package:datasets>
 [[9]] $ <env: package:methods>
[[10]] $ <env: Autoloads>
[[11]] $ <env: package:base>
[[12]] $ <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:stats"       "package:graphics"    "package:grDevices"  
 [7] "package:utils"       "package:datasets"    "package:methods"    
[10] "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:stats"       "package:graphics"   
 [7] "package:grDevices"   "package:utils"       "package:datasets"   
[10] "package:methods"     "Autoloads"           "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: 0x6160cbcc58b8>
<environment: namespace:stats>

Obrigado

Sugestões, perguntas, críticas…

Referências

BATISTA, B. D. O.; OLIVEIRA, D. A. B. J. R básico. Ouro Branco, MG, Brasil: [s.n.], 2022.