-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprocesar_constitucion.r
274 lines (241 loc) · 11.2 KB
/
procesar_constitucion.r
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
library(tidytext)
library(readr)
library(dplyr)
library(ggplot2)
#descargar pdf, de ser necesario
#download.file("https://www.oas.org/dil/esp/Constitucion_Chile.pdf",
# "constitucion.pdf")
#importar pdf
texto <- pdftools::pdf_text("constitucion.pdf")
#importar stopwords ----
# descargarlas
# stopwords <- readtext::readtext("https://raw.githubusercontent.com/stopwords-iso/stopwords-es/master/stopwords-es.txt") %>%
# unnest_tokens(palabra, text) %>%
# tibble() %>%
# select(palabra) %>%
# filter(nchar(palabra) > 1) %>%
# pull()
#cargar
load("stopwords.Rdata")
#constitución por líneas ----
#procesa la constitución para producir un data frame que contenga las líneas del pdf y también cada palabra en cada línea
constitucion <- texto %>%
#convertir a un data frame tipo tibble (por comodidad)
tibble() %>%
#generar número de cada párrafo (vienen del pdf)
mutate(n_parrafo = 1:n()) %>%
rename(caja = 1) %>%
#desarmar el texto en líneas
unnest_tokens(linea, caja,
token = "regex", pattern = "\n", #separar palabras en los espacios
to_lower = FALSE) %>% #sin tirar a minúsculas
mutate(n_linea = 1:n()) %>% #crear número de cada línea
mutate(linea = stringr::str_trim(linea)) %>% #borrar espacios al principio de las líneas
#recortar índice al inicio, e índice analítico al final, para no considerarlos
filter(n_linea >= 48) %>% #título de la constitución
filter(n_linea < 2903) %>% #título del índice analítico
mutate(n_linea = 1:n()) %>% #rehacer líneas
#desarmar las líneas en palabras
unnest_tokens(input = linea,
output = palabra,
token = "words", to_lower = FALSE, drop = FALSE) %>%
group_by(n_linea) %>%
mutate(n_palabra = 1:n()) %>% #numero de palabra en cada línea
#detectar y marcar capítulos
ungroup() %>%
mutate(linea_capitulo = case_when(palabra %in% c("CAPITULO", "CAPÍTULO") ~ n_linea)) %>% #detectar palabras
tidyr::fill(linea_capitulo) %>% #rellenar datos hacia abajo
mutate(linea_capitulo = as.numeric(as.factor(as.character(linea_capitulo)))) %>% #convertir secuencia a numeros de 1 en 1
mutate(linea_capitulo = tidyr::replace_na(linea_capitulo, 1)) %>% #capítulo 0 son las líneas antes del capítulo 1
#líneas inversas y escala horizontal
ungroup() %>%
mutate(n_linea_rev = max(n_linea)-n_linea) %>% #orden de línea inverso para eje y (la primera línea es el máximo, y la última línea es 1, cosa que al graficar el "texto" se vea en orden de arriba hacia abajo
group_by(n_linea) %>%
#aplicar escala a la posición de palabra, para "justificar" los puntos igual como se haría en Word
mutate(n_palabra_escala = (n_palabra - min(n_palabra) ) / (max(n_palabra) - min(n_palabra) ),
n_palabra_escala = replace(n_palabra_escala, is.na(n_palabra_escala), 0.1),
n_palabra_escala = replace(n_palabra_escala, n_palabra_escala==0, 0.03),
n_palabra_escala = replace(n_palabra_escala, n_palabra_escala==1, 0.97)) %>%
ungroup() %>%
#anexar líneas contextuales ----
left_join(constitucion %>%
filter(!(palabra %in% stopwords)) %>% #filtrar stopwords
filter(nchar(palabra) >= 4) %>%
select(!c(palabra, n_palabra, n_palabra_escala)) %>%
distinct() %>%
mutate(linea_contexto = paste0(lag(linea, default = ""), " ",
linea, " ",
lead(linea, default = ""))) %>%
mutate(linea_contexto = stringr::str_trim(linea_contexto, side="left")) %>%
select(n_linea, linea_contexto), by = "n_linea")
constitucion
glimpse(constitucion)
readr::write_rds(constitucion, file = "constitucion.rds")
#funciones ----
destacar_palabras_clave <- function(datos) {
datos %>%
mutate(palabras_clave = case_when(stringr::str_detect(palabra, "famili") ~ "Familia",
#stringr::str_detect(palabra, "chil") ~ "Chile",
stringr::str_detect(palabra, "social|sociedad") ~ "Social",
stringr::str_detect(palabra, "trabaj|empleo") ~ "Trabajo",
stringr::str_detect(palabra, "derech") ~ "Derechos",
stringr::str_detect(palabra, "empre|negoc") ~ "Empresas",
stringr::str_detect(palabra, "priva") ~ "Privado",
stringr::str_detect(palabra, "econ") ~ "Economía",
stringr::str_detect(palabra, "merca") ~ "Mercado",
TRUE ~ "Otros"),
palabras_clave = forcats::fct_relevel(after = 0, palabras_clave, "Otros")) %>%
mutate(palabras_alpha = if_else(palabras_clave=="Otros", "No", "Sí"))
}
#función que marca en una columna si se detecta la palabra entregada
destacar_palabra_elegida <- function(datos, palabra_elegida = NULL, partial_match = FALSE) {
#por si no hay palabra
if (is.null(palabra_elegida) | palabra_elegida == "" ) {
} else {
#match exacto con str_detect
if (partial_match == FALSE) {
datos <- datos %>%
ungroup() %>%
mutate(palabras_clave = case_when(stringr::str_detect(palabra, stringr::regex(as.character(palabra_elegida), ignore_case = T)) ~ stringr::str_to_sentence(palabra_elegida),
TRUE ~ as.character(palabras_clave)),
palabras_clave = as.factor(palabras_clave)) %>%
mutate(palabras_clave = forcats::fct_relevel(palabras_clave, "Otros", after = 0, )) %>%
mutate(palabras_alpha = if_else(palabras_clave == "Otros", "No", "Sí"))
#match parcial con stringdist
} else if (partial_match == TRUE) {
datos <- datos %>%
ungroup() %>%
mutate(palabras_clave = case_when(stringdist::ain(tolower(palabra), tolower(palabra_elegida), maxDist=2) ~ stringr::str_to_sentence(palabra_elegida),
TRUE ~ as.character(palabras_clave)),
palabras_clave = as.factor(palabras_clave)) %>%
mutate(palabras_clave = forcats::fct_relevel(palabras_clave, "Otros", after = 0, )) %>%
mutate(palabras_alpha = if_else(palabras_clave == "Otros", "No", "Sí"))
}
}
return(datos)
}
#prueba
constitucion %>%
mutate(palabras_clave = "Otros") %>%
destacar_palabra_elegida("política") %>%
destacar_palabra_elegida("santiago")
#prueba
constitucion %>%
mutate(palabras_clave = "Otros") %>%
destacar_palabra_elegida("política", partial_match = T) %>%
destacar_palabra_elegida("santiago")
#output: líneas cercanas
constitucion %>%
mutate(palabras_clave = "No") %>%
destacar_palabra_elegida("hogar") %>%
#destacar_palabra_elegida("santiago") %>%
###
mutate(linea_palabras_clave = case_when(palabras_clave != "No" ~ n_linea)) %>%
group_by(n_linea) %>%
mutate(linea_palabras_clave = case_when(!is.na(lead(linea_palabras_clave)) ~ n_linea,
!is.na(lag(linea_palabras_clave)) ~ n_linea,
TRUE ~ linea_palabras_clave)) %>%
filter(!is.na(linea_palabras_clave))
filter(n_linea >= linea_palabras_clave-3 & n_linea <= linea_palabras_clave+3)
#obtener líneas donde salen las palabras
constitucion %>%
mutate(palabras_clave = "No") %>%
destacar_palabra_elegida("facultades") %>%
#destacar_palabra_elegida("santiago") %>%
###
mutate(linea_palabras_clave = case_when(palabras_clave != "No" ~ n_linea)) %>%
select(linea_palabras_clave) %>% na.omit() %>% pull() -> lineas_2
#repetir con un magen de 3 arriba y abajo
lineas_3_arriba_abajo <- c(lineas_2 + rep(0:3, each = length(lineas_2)),
lineas_2 + rep(0:-3, each = length(lineas_2)))
#filtrar
constitucion %>%
select(-c(palabra, n_palabra, n_palabra_escala)) %>%
distinct() %>%
filter(n_linea %in% lineas_3_arriba_abajo) %>%
print(n=200)
#Tema ----
tema_constitucion <- theme(#strip.background = element_blank(),
#strip.text = element_blank(),
panel.spacing.y = unit(0, "cm"),
panel.grid = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(margin = margin(r = 12, l = -4)))
#Graficar palabras clave ----
constitucion %>%
filter(linea_capitulo == 5) %>%
#filter(n_linea < 500) %>%
ungroup() %>%
filter(!(palabra %in% stopwords)) %>% #filtrar stopwords
filter(nchar(palabra) > 1) %>%
filter(palabra != "Artículo") %>%
#destacar
destacar_palabras_clave() %>%
#graficar
ggplot(aes(n_palabra_escala, y = n_linea_rev)) +
geom_jitter(aes(color = palabras_clave,
#size = nchar(palabra),
size = palabras_alpha,
alpha = palabras_alpha),
height = 0, width=0.02) +
#geom_hline(yintercept=lineas, alpha=0.4) + #agregar capítulos
coord_cartesian(clip="off") +
#scale_color_discrete(h = c(0, 450), c=70, h.start = 100, l = 75,
# na.value = "black") +
scale_color_brewer(palette = "Set2", direction = -1) +
scale_alpha_manual(values = c(0.1, 1)) +
scale_size_manual(values = c(1, 2.5)) +
theme_minimal() +
tema_constitucion +
guides(size = FALSE,
alpha = FALSE,
col = guide_legend(reverse = TRUE,
override.aes = list(size=2, fill=NA, text=NA)))
#Graficar palabras elegidas ----
constitucion %>%
#filter(linea_capitulo == 5) %>%
filter(!(palabra %in% stopwords)) %>% #filtrar stopwords
filter(nchar(palabra) >= 4) %>%
filter(palabra != "Artículo") %>%
#destacar
mutate(palabras_clave = "Otros") %>%
destacar_palabra_elegida("política", partial_match = T) %>%
destacar_palabra_elegida("salud") %>%
destacar_palabra_elegida("agua") %>%
destacar_palabra_elegida("guerra") %>%
destacar_palabra_elegida("enemigo", partial_match = T) %>%
#graficar
ggplot(aes(n_palabra_escala, y = n_linea_rev)) +
#capa de abajo
geom_jitter(data = . %>% filter(palabras_clave == "Otros"),
aes(size = palabras_alpha,
alpha = palabras_alpha),
color = "gray70",
height = 0, width=0.02) +
#capa de arriba
geom_jitter(data = . %>% filter(palabras_clave != "Otros"), aes(color = palabras_clave,
#size = nchar(palabra),
size = palabras_alpha,
alpha = palabras_alpha),
height = 0, width=0.02) +
facet_wrap(~linea_capitulo, ncol = 1, scales="free",
strip.position = "left") +
coord_cartesian(clip="off") +
scale_color_brewer(palette = "Set2", direction = -1) +
scale_alpha_manual(values = c(0.1, 1)) +
scale_size_manual(values = c(1, 2.5)) +
scale_x_continuous(expand = expansion(mult = 0)) +
theme_minimal() +
tema_constitucion +
theme(strip.text = element_text(hjust=0.5, vjust=0, size = 7),
panel.spacing.y = unit(0.1, "cm")) +
guides(size = FALSE,
alpha = FALSE,
col = guide_legend(reverse = TRUE,
override.aes = list(size=2, fill=NA, text=NA)))
#pasar a ggiraph
#agrear interactive a la capa de arriba
stringdist::ain("constitución", "destitucional", maxDist=4)