Caso queira reproduzir essa pesquisa, clone o repositório e carregue o projeto
clicando no arquivo .RProj
.
git clone https://github.com/jtrecenti/brunoSalama
No RStudio, rode
devtools::use_data_raw() devtools::document() devtools::install()
Em seguida, rode os códigos do arquivo vignettes/bruno-salama.Rmd
cuidadosamente, chunk por chunk, verificando os resultados de cada passo. O
processo é instável pois depende de internet e configurações de OS. Recomendável
utilizar linux.
library(dplyr) library(stringr) library(tidyr) library(lubridate) library(purrr) library(httr) library(ggplot2) library(brunoSalama) knitr::opts_chunk$set(echo = FALSE)
Nesse estudo, vamos buscar dados no TJSP para ver se uma pesquisa é factível.
Hipótese: % de julgamento pró devedor muda de acordo com a taxa de juros.
d_cjpg <- list_cjpg(livre = 'emprestimo', data_inicial = '2014-01-01', data_final = '2014-12-31', min_pag = 1, max_pag = Inf, salvar = TRUE, path = 'data-raw/cjpg') devtools::use_data(d_cjpg, overwrite = TRUE)
n_cjpg(livre = 'emprestimo', data_inicial = '2014-01-01', data_final = '2014-12-31')
p <- d_cjpg %>% mutate(txt2 = tolower(desacentuar(txt))) %>% filter(!str_detect(txt2, 'financiamento de veiculo')) %>% distinct(n_processo) %>% with(n_processo)
d_result <- cpo_pg(p) arqs <- dir('data-raw/cpo-pg', full.names = TRUE)
d_cpopg <- parse_cpopg(arqs) devtools::use_data(d_cpopg, overwrite = TRUE)
d_partes <- d_cpopg %>% select(arq, partes) %>% unnest(partes) %>% rename(error = `"error"`) %>% filter(!is.na(arq)) %>% select(-error)
reu <- c('reqda', 'reqdo', 'reu', 'embargdo', 'exectdo', 're', 'imptdo', 'exectda') autor <- c('reqte', 'embargte', 'autor', 'exeqte', 'imptte', 'autora') banco <- c('bradesco', 'santander', 'itau', 'banco', 'bank', 'hsbc', 'unibanco') %>% str_c(collapse = '|') d_aux <- d_partes %>% count(forma, sort = TRUE) %>% mutate(tipo_forma = ifelse(forma %in% reu, 'reu', ifelse(forma %in% autor, 'autor', 'outros'))) d_partes_bancos <- d_partes %>% inner_join(d_aux, 'forma') %>% filter(tipo_forma != 'outros') %>% select(arq, tipo_forma, parte) %>% group_by(arq, tipo_forma) %>% summarise(parte = paste(parte, collapse = '\n')) %>% ungroup() %>% spread(tipo_forma, parte) %>% filter(!is.na(autor), !is.na(reu)) %>% mutate_each(funs(str_trim(gsub('Advog.*', '', .))), autor, reu) %>% mutate(n_processo = str_replace_all(arq, '[^0-9]', '')) %>% select(n_processo, autor, reu) %>% filter(str_detect(tolower(desacentuar(reu)), banco))
reais <- function(x) { tidyr::extract_numeric(gsub(',', '.', gsub('\\.', '', x))) } d_infos <- d_cpopg %>% select(arq, infos) %>% unnest(infos) %>% rename(error = `"error"`) %>% filter(!is.na(arq)) %>% select(-error) d_infos_spr <- d_infos %>% distinct(arq, key) %>% spread(key, value) %>% filter(area != 'Criminal') %>% mutate(valor = reais(valor_da_acao)) %>% mutate(digital = as.logical(digital)) %>% mutate(n_processo = str_replace_all(arq, '[^0-9]', '')) %>% mutate(data_distribuicao = as.Date(dmy(str_extract(distribuicao, '[^ ]+ ')))) %>% select(n_processo, digital, data_distribuicao, valor) %>% filter(!is.na(valor))
d_cjpg_util <- d_cjpg %>% mutate(n_processo = str_replace_all(n_processo, '[^0-9]', '')) %>% select(n_processo, magistrado, comarca, foro, vara, data_sentenca = data_de_disponibilizacao, cod_sentenca, txt) %>% mutate(data_sentenca = as.Date(dmy(data_sentenca))) %>% group_by(n_processo) %>% summarise(txt = paste(txt, collapse = '\n@@@\n'), magistrado = first(magistrado), comarca = first(comarca), foro = first(foro), vara = first(vara), data_sentenca = first(data_sentenca), cod_sentenca = first(cod_sentenca))
salario_minimo <- function(d) { # https://www.domesticalegal.com.br/conteudo/utilidades/salario-minimo-das-empregadas-domesticas.aspx if(d >= '2015-01-01') return(905) if(d >= '2014-01-01' & d <= '2014-12-31') return(810) if(d >= '2013-02-01' & d <= '2013-12-31') return(755) if(d >= '2012-03-01' & d <= '2013-01-31') return(690) if(d >= '2012-01-01' & d <= '2012-02-31') return(622) if(d >= '2011-04-01' & d <= '2011-12-31') return(600) if(d >= '2010-04-01' & d <= '2011-03-31') return(560) if(d >= '2010-01-01' & d <= '2010-03-31') return(510) if(d >= '2009-05-01' & d <= '2009-12-31') return(505) if(d >= '2009-02-01' & d <= '2009-04-31') return(465) if(d >= '2008-05-01' & d <= '2009-01-31') return(450) if(d >= '2008-03-01' & d <= '2008-04-31') return(415) if(d >= '2007-08-01' & d <= '2008-02-29') return(410) if(d >= '2007-04-01' & d <= '2007-07-31') return(350) if(d >= '2006-04-01' & d <= '2007-03-31') return(350) if(d >= '2005-05-01' & d <= '2006-03-31') return(300) if(d >= '2004-05-01' & d <= '2005-04-31') return(260) if(d >= '2003-04-01' & d <= '2004-04-31') return(240) if(d >= '2002-04-01' & d <= '2003-03-31') return(200) if(d >= '2001-04-01' & d <= '2002-03-31') return(180) if(d >= '2000-04-01' & d <= '2001-03-31') return(151) if(d >= '1999-05-01' & d <= '2000-03-31') return(136) if(d >= '1998-05-01' & d <= '1999-04-31') return(130) if(d >= '1997-05-01' & d <= '1998-04-31') return(120) } d_quase <- d_infos_spr %>% inner_join(d_cjpg_util, 'n_processo') %>% inner_join(d_partes_bancos, 'n_processo') %>% mutate(tempo = as.numeric(data_sentenca - data_distribuicao)) %>% filter(tempo > 0) %>% mutate(valor_sm = valor / sapply(data_sentenca, salario_minimo)) devtools::use_data(d_quase, overwrite = TRUE)
split_phrases <- function(x) { before_dot <- c('[^ ][^I]') before_dot <- paste(before_dot, collapse = '|') resplit <- paste0('(?<=((', before_dot, ')\\. {1,10}[A-ZÀÉÁÚ]))') banned_phrases <- c('^(DOCUMENTO ASSINA)', '^(Processo Fís)', '^(Processo n.?\\: ?[0-9])', '^(Classe +\\-)', '^(São Paulo, )', '^(Requerente\\:)', '^(Requerid.{1,3}\\:)', '^(Juiz(\\(a\\))? )', '^(Eu[, ]).+', '(crevi|subscr|digitei)\\.$', '^P\\. ?R\\. ?I\\.', '^R\\. ?P\\. ?I\\.') banned_phrases <- paste(banned_phrases, collapse = '|') re_dots <- c('Rel\\.$', 'Min\\.$', 'Col\\.$', 'Sra?\\.$', 'Exm[oa]\\.$', 'Dr(\\(a\\))?\\.$', 'inc\\.$') re_dots <- paste(re_dots, collapse = '|') linhas <- unlist(str_split(x, '\n')) frases <- stringi::stri_split_regex(linhas, resplit) frases <- lapply(frases, function(z) { if (length(z) > 1) { for (i in 2:length(z)) { z[i] <- paste0(str_sub(z[i - 1], -1), z[i]) z[i - 1] <- str_sub(z[i - 1], 1, -2) } } return(z) }) frases <- unlist(frases) frases <- str_trim(frases[!frases %in% c('')]) k <- 1 colar <- list(1) for (i in 2:length(frases)) { if (str_detect(frases[i - 1], re_dots)) { colar[[k]] <- append(colar[[k]], i) } else { colar <- append(colar, i) k <- k + 1 } } frases <- sapply(colar, function(x) paste(frases[x], collapse = ' ')) frases <- str_trim(frases[!frases %in% c('')]) frases <- frases[!str_detect(frases, banned_phrases)] return(frases) } d_cjpg_frases <- d_quase %>% select(n_processo, cod_sentenca, txt) %>% mutate(txt = gsub(' +', ' ', txt)) %>% group_by(n_processo, cod_sentenca) %>% do(frase = split_phrases(.$txt)) %>% ungroup %>% unnest(frase) %>% tbl_df %>% filter(str_detect(frase, '[a-zA-Z0-9]')) # saveRDS(d_cjpg_frases, 'data-raw/d_cjpg_frases.rds') # d_cjpg_frases <- readRDS('data-raw/d_cjpg_frases.rds') inicio_decisao <- c('^(.{0,8}Ante a?o exposto)', '^(.{0,8}Frente ao exposto)', '^(.{0,8}Diante dis[st]o)', '^(.{0,8}Is[st]o posto)', '^(.{0,8}Em razão do exposto)', '^(.{0,8}Do exposto)', '^(.{0,8}Pelo exposto)', '^(.{0,8}Posto isso)', '^(.{0,8}Diante, pois, de todo o exposto)', '^(.{0,8}Diante d?o exposto)', '^(.{0,8}Feitas as considerações supra)', '^(.{0,8}Por todo o exposto)', '^(.{0,8}Posto is[st]o|POSTO IS[T]O)', '^(.{0,8}Por es[st]as razões)', '^(.{0,8}Ante todo o exposto)', '^(.{0,8}De acordo com o exposto)', '^(.{0,8}De acordo com todo o exposto)', '^(.{0,8}Pelas razões expostas)', '^(.{0,8}Por tais motivos)', '^(.{0,8}Por tudo o quanto exposto)', '^(.{0,8}Nes[ts]es termos,? julgo)', '^(.{0,8}Em face do exposto)', '^(.{0,8}Pelos fundamentos alinhavados)', '^(.{0,8}Dessarte)', '^(.{0,8}Assim,)', '^(.{0,8}Ante o acima exposto)', '^(.{0,8}Pelos motivos expostos)', '^(.{0,8}Destarte)', '^(.{0,8}Ipso Facto)', '^(.{0,8}Pelo acima exposto)') %>% paste(collapse = '|') possiveis_resultados <- c( 'julg[oa](.{0,20})procedente', 'julg[oa](.{0,20})procedente em parte', 'julg[oa](.{0,20})parcialmente', 'julg[oa](.{0,20})(liminarmente |totalmente )?improcedente', 'julg[oa](.{0,20})extint[oa]', 'homologo.{5,30}' ) %>% paste(collapse = '|') sujeira <- c('^(@ )', 'JULG[OA]R?', 'LIMINARMENTE', '[0-9()\n:]', '(A )?AÇÃO', 'PEDIDO', 'TOTALMENTE', 'DEMANDA', 'AINDA', 'TAMBÉM') %>% paste(collapse = '|') sujeira2 <- '( |^)[A-Z] ' d_final_decisao <- d_cjpg_frases %>% mutate( tem = str_detect(frase, regex(inicio_decisao, ignore_case = TRUE)) & str_detect(frase, regex('julg[oa]r?', ignore_case = TRUE)), tem_a = str_detect(frase, regex('homologo', ignore_case = TRUE)), ext = str_detect(frase, regex('sem julgamento de m[eé]rito', ignore_case = TRUE)) ) %>% group_by(n_processo, cod_sentenca) %>% mutate( n = n(), result = ifelse(any(ext), paste(frase[last(which(ext)):first(n)], collapse = '\n'), 'nao tem'), result = ifelse(any(tem_a), paste(frase[last(which(tem_a)):first(n)], collapse = '\n'), result), result = ifelse(any(tem), paste(frase[last(which(tem)):first(n)], collapse = '\n'), result)) %>% ungroup %>% mutate( result_txt = sapply( str_extract_all(result, regex(possiveis_resultados, ignore_case = TRUE)), paste, collapse = ' @ ' )) %>% mutate( result_txt = toupper(result_txt), result_txt = gsub('PROCEDENTE EM PARTE', 'PARCIALMENTE', result_txt), result_txt = ifelse(str_detect(result_txt, regex('homolog', ignore_case = TRUE)) & str_detect(result, regex('acordo|concilia', ignore_case = TRUE)), 'ACORDO', result_txt) ) %>% # daqui vou tirar todo o resto e falar que é extincao de execucao. # filter(result_txt != '', # result_txt != 'JULGO EXTINTO', # result_txt != 'JULGO EXTINTA', # !(str_detect(result_txt, regex('homolog', ignore_case = TRUE)) & # !str_detect(result_txt, regex('proced', ignore_case = TRUE)))) %>% mutate(result_txt = gsub('(@ )?JULG[AO]R? (O FEITO )?EXTINT[OA]', '', result_txt), result_txt = gsub('^(@ )', '', result_txt), result_txt = str_trim(result_txt)) %>% filter(result_txt != '') %>% mutate(result_txt = str_trim(result_txt)) %>% mutate(result_txt = gsub(sujeira, '', result_txt), result_txt = gsub(sujeira2, ' ', result_txt), result_txt = gsub(' +', ' ', result_txt), result_txt = gsub('HOMOLOGO[^@]+(@ |$)', '', result_txt), result_txt = gsub('( @) *$', '', result_txt), result_txt = gsub('INPRO', 'IMPRO', result_txt), result_txt = str_trim(result_txt)) %>% # filter(!str_detect(result_txt, 'EXTINT|IMPARCIALM')) %>% I() saveRDS(d_final_decisao, 'data-raw/d_final_decisao.rds') # d_final_decisao <- readRDS('data-raw/d_final_decisao.rds') # ------------------------------------------------------------------------- d_final <- d_final_decisao %>% group_by(n_processo, cod_sentenca) %>% summarise(result = paste(unique(result_txt), collapse = ' @ ')) %>% ungroup() %>% filter(result != '') %>% mutate(result = gsub('Á IMP|DA IMP', 'IMP', result)) %>% mutate(result = gsub('DA PAR', 'PAR', result)) %>% mutate(result = gsub('[^ ]+ IMP', 'IMP', str_trim(result))) %>% mutate(result = ifelse(str_detect(result, 'PARCIAL|EM PARTE'), 'PARCIALMENTE', result)) %>% mutate(result = sapply(result, function(x) { paste(unique(str_trim(unlist(str_split(x, ' @ ')))), collapse = ' @ ') })) %>% filter(!str_detect(result, 'ACORDO|EXT')) %>% mutate(result = ifelse(str_detect(result, '@'), 'PARCIALMENTE', result)) %>% mutate(result = gsub('P+', 'P', result), result = gsub('^M', 'IM', result)) %>% mutate(result = ifelse(str_detect(result, 'PARCIALMENTE'), 'PARCIALMENTE', ifelse(str_detect(result, 'PROCEDENTE') & !str_detect(result, 'IMP'), 'PROCEDENTE', ifelse(str_detect(result, 'IMPROCEDENTE') & !str_detect(result, 'PROCEDENTE'), 'IMPROCEDENTE', ifelse(str_detect(result, 'IMPROCEDENTE'), 'IMPROCEDENTE', ifelse(str_detect(result, 'PROCEDENTE'), 'PROCEDENTE', 'AAAHHH')))))) %>% { left_join(d_quase, ., c('n_processo', 'cod_sentenca')) } %>% tidyr::replace_na(list(result = 'ACORDO/EXTINTO/VAZIO')) # d_final_decisao %>% # filter(tem | tem_a | ext) %>% # distinct(n_processo, cod_sentenca) %>% # {anti_join(d_final, ., c("n_processo", "cod_sentenca"))} %>% # View # d_cjpg_decisao_complete <- d_cjpg_decisao %>% # inner_join( # select(d_cjpg_one, cod_sentenca, n_processo, classe, assunto, magistrado, # foro, vara, data_disp), # c('cod_sentenca', 'n_processo') # ) %>% # inner_join(select(d_final, n_processo, digital, valor_da_acao, empresa, # reqte_adv, reqdo_adv), # 'n_processo') devtools::use_data(d_final, overwrite = TRUE) # valor, tempo, resultado, juiz, vara, juros
d_final %>% count(result, sort = TRUE) %>% mutate(prop = scales::percent(n / sum(n))) %>% DT::datatable()
d_final %>% count(magistrado, sort = TRUE) %>% mutate(prop = scales::percent(n / sum(n))) %>% DT::datatable()
d_final %>% count(magistrado, result) %>% mutate(prop = round(n / sum(n), 4)) %>% select(-n) %>% spread(result, prop, fill = 0) %>% inner_join(count(d_final, magistrado), 'magistrado') %>% ungroup() %>% arrange(desc(n)) %>% select(magistrado, n, everything()) %>% DT::datatable()
d_final %>% glimpse()
d_final %>% ggplot(aes(x = data_distribuicao, fill = digital)) + geom_density(alpha = 0.5)
Observa-se que os processos digitais são mais recentes. Isso é óbvio, mas significa que não é possível comparar o tempo de processos digitais e físicos, pois há uma truncagem e só consideraríamos os processos digitais mais recentes.
d_final %>% ggplot(aes(x = data_sentenca)) + geom_histogram(aes(y = ..density..), fill = 'lightblue', colour = 'black', bins = 30) + geom_density(alpha = 0.3, fill = 'royalblue')
Observa-se algumas flutuações e uma queda de produtividade no final/início do ano, mas nada muito relevante
d_final %>% ggplot(aes(x = tempo)) + geom_histogram(aes(y = ..density..), fill = 'lightblue', colour = 'black', bins = 60) + geom_density(alpha = 0.3, fill = 'royalblue')
quantile(d_final$tempo, 0:10 / 10)
O tempo é altamente assimétrico, apresentando
r sum(d_final$tempo > 365 * 10)
valores que podem ser
considerados aberrantes (> 10 anos). Sugere-se remover
essas observações.
d_final %>% count(comarca, sort = TRUE) %>% mutate(prop = scales::percent(n / sum(n))) %>% DT::datatable()
Por quê Campinas/Guarulhos não está em segundo? Por quê Franca está em segundo? Possível explicação: viés na disponibilidade dos dados.
d_final %>% count(comarca, result) %>% mutate(prop = round(n / sum(n), 4)) %>% select(-n) %>% spread(result, prop, fill = 0) %>% inner_join(count(d_final, comarca), 'comarca') %>% select(comarca, n, everything()) %>% ungroup() %>% dplyr::arrange(desc(n)) %>% DT::datatable()
Também é possível notar que as decisões mudam bastante por comarca...
d_final %>% count(foro, comarca, result) %>% mutate(prop = round(n / sum(n), 4)) %>% select(-n) %>% spread(result, prop, fill = 0) %>% inner_join(count(d_final, foro, comarca), c('comarca', 'foro')) %>% select(comarca, foro, n, everything()) %>% ungroup() %>% dplyr::arrange(desc(n)) %>% DT::datatable()
... E por foro...
d_final %>% filter(comarca == 'SÃO PAULO') %>% count(foro, vara, result) %>% mutate(prop = round(n / sum(n), 4)) %>% select(-n) %>% spread(result, prop, fill = 0) %>% inner_join(count(d_final, foro, vara), c('vara', 'foro')) %>% select(foro, vara, n, everything()) %>% ungroup() %>% dplyr::arrange(desc(n)) %>% DT::datatable()
... E por vara.
dollar <- function(x) round(x, 2) d_final %>% summarise(media = mean(valor_sm), sd = sd(valor_sm), min = min(valor_sm), `1quart` = quantile(valor_sm, .25), mediana = median(valor_sm), `3quart` = quantile(valor_sm, .75), max = max(valor_sm)) %>% mutate_each(funs(dollar)) %>% DT::datatable()
Pode-se observar que a variável é altamente assimétrica
d_final %>% group_by(comarca) %>% summarise(n = n(), media = mean(valor_sm), sd = sd(valor_sm), min = min(valor_sm), `1quart` = quantile(valor_sm, .25), mediana = median(valor_sm), `3quart` = quantile(valor_sm, .75), max = max(valor_sm)) %>% mutate_each(funs(dollar), -n, -comarca) %>% arrange(desc(n)) %>% DT::datatable()
d_final %>% group_by(result) %>% summarise(n = n(), media = mean(valor_sm), sd = sd(valor_sm), min = min(valor_sm), `1quart` = quantile(valor_sm, .25), mediana = median(valor_sm), `3quart` = quantile(valor_sm, .75), max = max(valor_sm)) %>% mutate_each(funs(dollar), -n, -result) %>% arrange(desc(n)) %>% DT::datatable()
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.