07 outubro, 2021

Selo DC

Motivação

Consideremos um banco de dados com informações de um grupo de pessoas, tais como o nome, altura (cm), peso (kg), idade (anos), que segue:

dados <- data.frame(
  nome = c("Paulo", "Maria", "Caio"),
  altura = c(175, 167, 172),
  peso = c(70, 65, 7500),
  idade = c(32, 26, 19)
); dados
##    nome altura peso idade
## 1 Paulo    175   70    32
## 2 Maria    167   65    26
## 3  Caio    172 7500    19
# Substituicao
dados[3, 3] <- 75; dados
##    nome altura peso idade
## 1 Paulo    175   70    32
## 2 Maria    167   65    26
## 3  Caio    172   75    19

Função de substituição primitiva (Ideia)

`[<-` <- function(x, i, value){
  # Corpo da funcao
}
# Chamada de funcao
x[i] <- value
# Chamada de forma equivalente
`[<-`(x, i, value)

Aprofundando

# Vamos criar um vetor de comprimento 10
x <- 1:10; x
##  [1]  1  2  3  4  5  6  7  8  9 10
# Usando a funcao de substituicao, para alterar
# dois valores na posicao 6 e 10
x[c(6, 10)] <- c(100, 200); x
##  [1]   1   2   3   4   5 100   7   8   9 200

Por trás do código

# Objeto x criado
x <- 1:10
# `*tmp*` temporariamente criado
`*tmp*` <- x
# Alteracoes realizadas
x <- `[<-`(`*tmp*`, c(6, 10), valor = c(100, 200)); x
##  [1]   1   2   3   4   5 100   7   8   9 200
# Ao final se remove `*tmp*`
rm(`*tmp*`)

Discutindo o código para função “:”

# Vamos criar um vetor de comprimento 10
x <- 1:10; x
## [1]  1  2  3  4  5  6  7  8  9 10

# Inspecionando o objeto
tracemem(x)
## [1] "<000000965C8A97D8"

.Internal(inspect(x))
## @0x000000965c8a97d8 13 INTSXP g0c0 [REF(65535),TR]  1 : 10 (compact)

# Usando a funcao de substituicao, para alterar
# dois valores na posicao 6 e 10
x[c(6, 10)] <- c(100, 200); x
## tracemem[0x000000965c8a97d8 - 0x000000965bdf6bc0]: 
## tracemem[0x000000965bdf6bc0 - 0x000000965f177418]: 
## [1]   1   2   3   4   5 100   7   8   9 200

# Inspecionando novamente o objeto
.Internal(inspect(x))
## @0x000000965f177418 14 REALSXP g0c5 [REF(5),TR] (len=10, tl=0) 1,2,3,4,5,...

Criando a nossa função de substituição

# Funcao de substituicao de alterar os extremos
`substextr<-` <- function(x, value) {
  x <- sort(x)
  x[1] <- x[length(x)] <- value
  x
}
# Criando o vetor
set.seed(10)
x <- rnorm(10)
# Inspecao
.Internal(address(x))
## <pointer: 0x000000000837d8b8>
# Alterando o vetor
substextr(x) <- 100
# Inspecao
.Internal(address(x))
## <pointer: 0x0000000008282f78>

Inserindo mais argumentos

`subst<-` <- function(x, i, value) {
  x[i] <- value
  x
}
set.seed(10)
(x <- c(1, 2, 3))
## [1] 1 2 3
# Inspecao
.Internal(address(x))
## <pointer: 0x0000000009fdc6f8>
# subst(x, i) <- value
subst(x, 2) <- 100; x
## [1]   1 100   3
# Inspecao
.Internal(address(x))
## <pointer: 0x000000000a03a690>

Bons estudos!