{tidyverse}, Simulações e Processamento de Séries Temporais
Só para deixar tudo bem claro quanto ao que eu quero dizer quando falo em uma função impura: se fornecida os mesmos argumentos devolverá o mesmo resultado. É simples construir alguns exemplos.
## [1] "2020-12-11 07:03:25 -03"
## [1] "2020-12-11 07:03:22 -03"
## [1] "2020-12-11 07:03:40 -03"
Funções impuras também podem assim ser porque desencadeiam efeitos colaterais, como por exemplo escrever algum arquivo na memória.
Isso não é necessariamente ruim, o objetivo final de código em produção é desencadear efeitos colaterais, mas isso leva à código com consequências menos claras e por isso eu aprendi nos manuais e com os erros a evitar impureza. Pelo exercício vou tentar ilustrar uma aplicação onde impureza traz ergonomia.
É bem comum que eu simule dados de processos estocásticos aqui. Um AR1 com , por exemplo:
## # A tibble: 1,000 x 2
## t y
## <int> <dbl>
## 1 1 0.229
## 2 2 1.68
## 3 3 1.94
## 4 4 3.28
## 5 5 3.28
## 6 6 3.03
## 7 7 4.01
## 8 8 4.09
## 9 9 3.75
## 10 10 6.03
## # … with 990 more rows
E tem duas coisas aí que eu gostaria de mudar:
- Referência explícita e repetida ao tamanho da amostra, que é sempre igual e dado pelo tamanho do tibble, contextual
- Me referir ao processo gerador com alguma abstração, ao invés de explicitamente simular choques e soma-los.
Podemos resolver isso tudo em uma função que (i) sabe que precisa gerar um AR1 com certo e (ii) é agnóstica em relação à distribuição dos choques.
Primeiro, descobrir se a função foi chamada em um contexto de dados, dentro de um tibble. A ideia aqui é olhar como se comporta dplyr::n
, que traz a informação contextual do tamanho do tibble usado como ambiente quando foi executada. Se não foi chamada dentro de um tibble, vai retornar erro:
## Error: `n()` must only be used inside dplyr verbs.
## # A tibble: 2 x 2
## sinal N
## <lgl> <int>
## 1 FALSE 81
## 2 TRUE 19
Dito isso, precisamos capturar o erro, caso ocorra, então é bom embrulhar a função em algum advérbio do purrr.
E agora a função que simula o processo em si.
E agora podemos fazer coisas como isso:
Um próximo passo seria extrair alguns momentos ao longo do tempo nesses processos. Para isso não precisamos implementar soluções, o slider
dá conta. É uma espécie de purrr
para operações em janelas móveis. Nele a prima mais próxima de purrr::map
é slider::slide
, que também tem variantes tipadas com terminações em _lgl
, _dbl
e etc.