-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathpacotes.Rmd
224 lines (192 loc) · 9.35 KB
/
pacotes.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# Pacotes {#pacotes}
Nas palavras do maior guru do R, Hadley Wickham, "pacotes são a unidade
fundamental de código R reprodutível". Toda vez que você utiliza a função
`library()`, algum pacote está sendo carregado na sessão. Muitas vezes criar uma
biblioteca de funções pode parecer uma tarefa árdua e confusa, restrita apenas a quem possui grande conhecimento da linguagem, mas essa impressão não poderia estar mais
distante da realidade: pacotes para o R são bastante simples e intuitivos de
fazer.
No início deste livro foi abordado o conceito de projeto. Ele não passa de um
arquivo `.Rproj` que indica para o RStudio que aquele diretório é um ambiente de
trabalho estruturado. Nesse sentido, pacotes são iguais a projetos porque eles
também têm um `.Rproj`; pacotes na verdade *são* projetos.
A diferença entre os dois é que pacotes podem ser documentados e instalados,
permitindo toda uma gama de novas possibilidades para quem programa.
Muitas vezes uma análise de dados pode envolver dezenas de funções e diversas
pessoas, fazendo com que o compartilhamento de código seja vital para que a
análise não fuja do controle. Pacotes permitem gerenciar dependências, manter
documentação, executar testes unitários e muito mais com o objetivo de deixar
todo o time na mesma página.
Sendo assim, recomenda-se criar um pacote para qualquer análise que envolva pelo
menos meia dúzia de funções complexas e mais de uma pessoa, caso contrário, um
projeto já é suficiente. Outra motivação para criar um pacote é compartilhar
conjuntos úteis de funções com outras pessoas; isso acaba sendo menos comum para
a maioria das pessoas, mas é importante ressaltar que o R não seria a linguagem
popular que é hoje se não fossem pelas famosas bibliotecas `ggplot2` e `dplyr`.
```r
usethis::create_package("~/Documents/demo")
#> ✔ Setting active project to '~/Documents/demo'
#> ✔ Creating 'R/'
#> ✔ Writing 'DESCRIPTION'
#> Package: demo
#> Title: What the Package Does (One Line, Title Case)
#> Version: 0.0.0.9000
#> Authors@R (parsed):
#> * First Last <[email protected]> [aut, cre] (<https://orcid.org/YOUR-ORCID-ID>)
#> Description: What the package does (one paragraph).
#> License: What license it uses
#> Encoding: UTF-8
#> LazyData: true
#> ✔ Writing 'NAMESPACE'
#> ✔ Writing 'demo.Rproj'
#> ✔ Adding '.Rproj.user' to '.gitignore'
#> ✔ Adding '^demo\\.Rproj$', '^\\.Rproj\\.user$' to '.Rbuildignore'
#> ✔ Opening '~/Documents/demo/' in new RStudio session
#> ✔ Setting active project to 'demo'
```
A função executada acima é exatamente análoga à função de criação de projetos.
A principal diferença é que ela cria um arquivo `DESCRIPTION` e assume que o
nome do pacote é igual ao nome da pasta onde o mesmo está sendo criado (neste
caso, "demo"). Alguns outros arquivos também são criados (como `.Rbuildignore` e
`NAMESPACE`), mas eles não vêm ao caso. De resto, o pacote é idêntico a um
projeto e pode ser sincronizado com o Git exatamente da mesma maneira.
O primeiro passo para começar a usar um pacote é atribuir a ele uma licença
(caso um dia você resolva compartilhá-lo com o mundo) e preencher a descrição.
Abaixo encontra-se uma função simples que adiciona uma licença MIT ao pacote.
```r
usethis::use_mit_license("Seu Nome")
#> ✔ Setting active project to '~/Documents/demo'
#> ✔ Setting License field in DESCRIPTION to 'MIT + file LICENSE'
#> ✔ Writing 'LICENSE.md'
#> ✔ Adding '^LICENSE\\.md$' to '.Rbuildignore'
#> ✔ Writing 'LICENSE'
```
O arquivo de descrição, no entanto, é um pouco mais complexo porque ele tem
alguns campos que precisam ser preenchidos manualmente. Quando o pacote for
criado, eles já estarão populados com instruções para facilitar a vida de quem programa. Abaixo está um exemplo de como `DESCRIPTION` deve ficar depois de
completo:
```
Package: demo
Title: O Que o Pacote Faz (Uma Linha)
Version: 0.0.0.9000
Authors@R:
person(given = "Seu",
family = "Nome",
role = c("aut", "cre"),
email = "[email protected]")
Description: O que o pacote faz (um paragrafo curto terminado em ponto final).
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
```
A partir deste ponto, os metadados do pacote estão essencialmente prontos e não
precisam mais ser modificados. Assim como em um projeto, o que resta é adicionar
arquivos com funções à pasta `R/`.
## Documentação
Para poder programar pacotes com mais facilidade, é necessário instalar o
`devtools`. Assim como o `tidyverse`, este é um conjunto de pacotes (que inclui
o `usethis` por sinal) que auxiliam no processo de criar e testar um pacote de
R.
```r
install.packages("devtools")
```
A partir de agora você pode, por exemplo, criar documentações para as funções do
seu pacote. Quando outras pessoas o instalarem, elas poderão consultar esses
manuais da mesma forma que fazem com qualquer outra função: `?funcao()`.
A documentação mais simples (e obrigatória) envolve dar um título para a função
e descrever o que cada parâmetro significa. Para documentar uma função qualquer,
basta adicionar comentários em cima dela com `#'` assim como no exemplo abaixo:
```r
#' Função demonstrativa que soma e imprime
#'
#' @param x Um número ou vetor numérico
#' @param y Um número ou vetor numérico
#' @param ... Outros argumentos passados para [print()]
#'
#' @export
funcao_demo <- function(x, y, ...) {
z <- x + y
print(z, ...)
return(z)
}
```
No RStudio, esse tipo de documentação é tratado diferentemente de outros
comentários, então certas palavras-chave ficam coloridas. `@param` por exemplo
indica a documentação de um dos parâmetros e `@export` indica que aquela função
será exportada pelo pacote, ou seja, ficará disponível quando for
executado o comando `library(demo)`.
Para gerar a documentação do pacote, basta chamar uma outra função do
`devtools`:
```r
devtools::document()
#> Updating demo documentation
#> Updating roxygen version in ~/Documents/demo/DESCRIPTION
#> Writing NAMESPACE
#> Loading demo
#> Writing NAMESPACE
#> Writing funcao_demo.Rd
?funcao_demo()
#> Rendering development documentation for 'funcao_demo'
```
```{r}
knitr::include_graphics("static/pacotes/doc.png")
```
Conforme o número de funções no pacote for crescendo, basta iterar nesse ciclo
descrito até aqui. Além disso, é importante lembrar (como destacado na sessão
anterior) que qualquer função utilizada de outro pacote deve ser invocada na
forma `pacote::funcao()`; neste momento, o pacote em questão se tornará uma
*dependência* do seu pacote e deve ser declarado como tal com
`usethis::use_package("pacote")` (mais sobre isso a seguir).
Para garantir que o R não encontrará nenhum problema no seu pacote, basta
executar a função de verificação `devtools::check()`. Se nenhum defeito for
encontrado, basta compartilhar o pacote com a comunidade e instalá-lo com
`devtools::install_local()`.
```r
devtools::check()
#> Updating demo documentation
#> Writing NAMESPACE
#> Loading demo
#> Writing NAMESPACE
#> ── Building ───────────────────────────────────────────────────────── demo ──
#> Setting env vars:
#> ● CFLAGS : -Wall -pedantic -fdiagnostics-color=always
#> ● CXXFLAGS : -Wall -pedantic -fdiagnostics-color=always
#> ● CXX11FLAGS: -Wall -pedantic -fdiagnostics-color=always
#> ─────────────────────────────────────────────────────────────────────────────
#> ✔ checking for file ‘/home/clente/Documents/demo/DESCRIPTION’ ...
#>
#> [... omitido por brevidade ...]
#>
#> ── R CMD check results ───────────────────────────────── demo 0.0.0.9000 ────
#> Duration: 8.2s
#>
#> 0 errors ✔ | 0 warnings ✔ | 0 notes ✔
```
## Imports
Como dito anteriormente, um passo importante na criação de um pacote é a
declaração de suas dependências. Se você tiver seguido com cuidado a sugestão de
já começar a escrever o pacote declarando todas as importações explicitamente
(ou seja, com `pacote::funcao()`), isso não será um problema, pois o
`devtools::check()` já será capaz de apontar exatamente quais dependências ainda
precisam ser registradas.
Suponha que um pacote tem exatamente duas dependências: o `dplyr` e o `kuber`
(um pacote desenvolvido pela Curso-R e disponível somente via GitHub). Para
passar no `check()` basta executar os dois comandos abaixo:
```r
usethis::use_package("dplyr")
usethis::use_dev_package("kuber")
```
O `dplyr`, por estar disponível no CRAN, não é um pacote considerado em fase de
desenvolvimento, então basta usar `usethis::use_package()`. Já o `kuber` só está
disponível no GitHub e instalável via `remotes::install_github("curso-r/kuber")`,
então precisamos neste caso utilizar `usethis::use_dev_package()`. Os comandos
acima criam uma nova seção no arquivo `DESCRIPTION`:
```
Imports:
dplyr,
kuber (>= 0.3.1.9000)
Remotes:
curso-r/kuber
```
Note que o `kuber` já é importado com um link remoto para o seu repositório no
GitHub e um marcador da versão atualmente instalada na sua máquina. Para saber
mais sobre versões, consulte o Capítulo \@ref(versoes-releases).