forked from leobarone/mq_ufmg_17
-
Notifications
You must be signed in to change notification settings - Fork 4
/
mq_ufmg_2018_tutorial05.Rmd
147 lines (98 loc) · 8.11 KB
/
mq_ufmg_2018_tutorial05.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
# Tutorial 5 - Análise de texto no R - pacote _stringr_
_Autor_: Leonardo Sangali Barone
_Revisão_: Rogério Jerônimo Barbosa
### Webscrapping para capturar material para o tutorial
Nossa primeira tarefa será obter um conjunto de textos com o qual trabalharemos. Classicamente, tutoriais de R sobre strings e mineração de texto utilizam "corpus" (já veremos o que é isso) de literatura moderna.
Para tornar nosso exemplo mais interessante, vamos utilizar discursos na Câmara dos Deputados. Em particular, vamos raspar todos os discursos da Deputada Luiza Erundina no site da Câmara dos Deputados.
A primeira ferramenta que veremos neste tutorial é o pacote _stringr_, que é parte do Vamos começar carregando os pacotes _rvest_ e _stringr_:
```{r, echo = F}
library(rvest)
library(stringr)
```
A seguir, vamos salvar em um objeto a página que contém uma tabela com os links para os discursos. Note que quando fazemos pesquisa de discurso na Câmara dos Deputados obtemos apenas 20 discursos por página. Alterando o argumento "Pagesize" no url conseguimos obter todos (480) os links em uma página única.
```{r}
url_tabela_discursos <- "http://www.camara.leg.br/internet/sitaqweb/resultadoPesquisaDiscursos.asp?txOrador=Luiza+Erundina&txPartido=PSOL&txUF=SP&dtInicio=&dtFim=&txTexto=&txSumario=&basePesq=plenario&CampoOrdenacao=dtSessao&PageSize=50&TipoOrdenacao=DESC&btnPesq=Pesquisar"
```
Vamos capturar os links de cada discurso. Examine a url antes de prosseguir para aprender um pouco mais de webscrapping.
```{r}
url_discursos <- url_tabela_discursos %>%
read_html() %>%
html_nodes(xpath = "//a[contains(@title, 'do Discurso')]") %>%
html_attr(name = "href")
```
O resultado é um vetor com o conteúdo dos atributos "href". Os url obtidos, entranto, têm problemas: falta o início do URL e há espaços onde não deveria haver. Precisamos adicionar o início da url para indicar que estamos navegando no servidor da Câmara e retirar os espaços vazios do url, que não são um problema para um browser como o Firefox, mas é um problema para o R.
Aproveitemos para ver duas funções novas, ambas do pacote _stringr_. Várias delas, como veremos, são semelhantes a funções de outros pacotes com as quais já trabalhamos. Há, porém, algumas vantagens ao utilizá-las: bugs e comportamentos inesperados corrigidos, uso do operador "pipe", nomes intuitivos e sequência de argumentos intuitivos.
_str\_c_ (aka string concatenar) é uma função semelhante a _paste0_ e serve para concatenar dois pedaços de texto, inclusive quando a operação for entre um texto e um vetor e entre vetores.
_str\_replace\_all_, por sua vez, substitui no texto um padrão por outro, respectivamente na sequência de argumentos. Seu uso é semelhante à função _gsub_, mas os argumentos estão em ordem intuitiva. Por exemplo, estamos substituindo espaço (incluindo tabs, quebras de linha etc) por nada nos url:
```{r}
url_discursos <- str_c("http://www.camara.leg.br/internet/sitaqweb/", url_discursos)
url_discursos <- str_replace_all(url_discursos, "[[:space:]]", "") # procure saber mais sobre "expressões regulares"
```
Vamos agora passar por todos os urls e obter os discursos. Examine a primeira url do vetor antes de prosseguir para aprender um pouco mais de webscrapping. Gravaremos os discursos em um objeto chamado "discursos", e cada posição conterá um discurso.
```{r}
discursos <- c()
for (i in 1:length(url_discursos)) {
print(i)
url_discurso <- url_discursos[i]
discurso <- url_discurso %>%
read_html() %>%
html_nodes(xpath = "//div[@id = 'content']//p") %>%
html_text()
discursos <- c(discursos, discurso)
Sys.sleep(0.3) # entre cada uma das raspagens, damos um tempinho... para não sobrecarregar o servidor
}
```
### Funcionalidades do _stringr_
Qual é o tamanho de cada discurso? Vamos aplicar _str\_length_ para descobrir. Seu uso é semelhante ao da função _nchar_:
```{r}
len_discursos <- str_length(discursos)
len_discursos
```
Vamos agora observar quais são os discursos nos quais a deputada menciona "Constituição". Para tanto, usamos _str\_detect_
```{r}
str_detect(discursos, "Constituição")
```
Poderíamos usar o vetor lógico resultante para gerar um subconjunto dos discursos, apenas com aqueles nos quais a palavra "Constituição" é mencionada. Mais simples, porém, é utilizar a função _str\_subset_, que funciona tal qual _str\_detect_, mas resulta num subconjunto em lugar de um vetor lógico:
```{r}
discursos_constituicao <- str_subset(discursos, "Constituição")
```
Se quisessemos apenas a posição no vetor dos discursos que contêm "Constituição", _str\_which_ faria o trabalho (função semelhante à _grep_ do R Base):
```{r}
str_which(discursos, "Constituição")
```
Voltando ao vetor completo, quantas vezes "Constituição" é mencionada em cada discursos? Qual é o máximo de menções a "Constituição" em um único discurso?
```{r}
str_count(discursos, "Constituição")
max(str_count(discursos, "Constituição"))
```
Vamos fazer uma substituição nos discursos. No lugar de "Constituição" colocaremos a expressão "Constituição, aquele pedaço de papel que não vale nada,". Podemos fazer a substituição com _str\_replace_ ou com _str\_replace\_all_. A diferença entre ambas é que _str\_replace_ substitui apenas a primeira ocorrênca encontrada, enquanto _str\_replace\_all_ substitui todas as ocorrências.
```{r}
str_replace(discursos_constituicao, "Constituição", "Constituição, aquele pedaço de papel que não vale nada,")
str_replace_all(discursos_constituicao, "Constituição", "Constituição, aquele pedaço de papel que não vale nada,")
```
Em vez de substituir, queremos conhecer a posição das ocorrências de "Constituição". Com _str\_locate_ e _str\_locate\_all_, respectivamente para a primeira ocorrência e todas as ocorrências, obtemos a posição de começo e fim do padrão buscado:
```{r}
str_locate(discursos_constituicao, "Constituição")
str_locate_all(discursos_constituicao, "Constituição")
```
Finalmente, notemos que os discursos começam sempre mais ou menos da mesma forma. Vamos retirar os 100 primeiros caracteres de cada discurso para observá-los. Usamos a função _str\_sub_, semelhante à função _substr_, para extrair um padaço de uma string:
```{r}
str_sub(discursos, 1, 100)
```
As posições para extração de exerto podem ser variáveis. Por exemplo, vamos usar "len_discursos" que criamos acima para extrair os 50 últimos caracteres de cada discurso:
```{r}
str_sub(discursos, (len_discursos - 50), len_discursos) # criamos o objeto 'len_discursos' mais acima, veja lá
```
Note que alguns discursos começam e terminam com espaços. Para nos livrarmos deles (apenas daqueles no começo e fim da string), utilizamos _str\_trim_:
```{r}
str_trim(discursos)
```
Infelizmente, não há tempo suficiente para entrarmos neste tutorial em um tema extremamante útil: expressões regulares (já mencionamos isso um pouco mais acima...). Expressões regulares, como podemos deduzir pelo nome, são expressões que nos permite localizar -- e, portanto, substituir, extrair, parear, etc -- sequências de caracteres com determinadas caraterísticas -- por exemplo, "quaisquer caracteres entre parênteses", ou "qualquer sequência entre espaços que comece com 3 letras e termine com 4 números" (tal com são as placas de automóvel).
Você pode ler um pouco sobre expressões regulares no R [aqui](https://rstudio-pubs-static.s3.amazonaws.com/74603_76cd14d5983f47408fdf0b323550b846.html) se tiver tempo em sala de aula. Com o uso de expressões regulares, outros dois pares de funções são bastante úteis _str\_extract_, _str\_extract\_all_, _str\_match_ e _str\_match\_all_.
## Nuvem de Palavras
Com a função _wordcloud_ do pacote de mesmo nome, podemos rapidamente visualizar as palavras discursadas tendo o tamanho como função da frequência (vamos limitar a 50 palavras):
```{r}
library(wordcloud)
wordcloud(discursos, max.words = 50)
```
Ainda não está não muito bonita... Mas vai melhorar! Voltaremos a fazer nuvem de palavras depois de aprendermos outra maneiras de trabalharmos com texto como dado no R. Veja o Tutorial 6!