The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
Esta vignette percorre o módulo quantitativo do
acR em cima de um corpus de discursos parlamentares
fabricado para o exemplo. Cada etapa é apresentada com uma pergunta
metodológica — por que faço isso? — antes do código e do
gráfico.
O caminho é o clássico da análise de conteúdo estatística: corpus → limpeza → tokenização → frequências → distintividade → visualização.
O módulo quantitativo tem seis técnicas centrais. Aprender qual usar em cada situação vale mais que decorar sintaxe:
| Pergunta | Técnica | Função |
|---|---|---|
| Que palavras dominam o corpus como um todo? | Frequência bruta | ac_count() → ac_top_terms() |
| Que palavras são distintivas de cada documento vs. o resto? | TF-IDF | ac_tf_idf() → ac_plot_tf_idf() |
| Que palavras separam um grupo do outro estatisticamente? | Keyness | ac_keyness() → ac_plot_keyness() |
| Que palavras andam juntas (associação sintagmática)? | Coocorrência | ac_cooccurrence() →
ac_plot_cooccurrence() |
| Onde no texto um termo aparece com mais frequência? | X-ray plot | ac_plot_xray() |
| Panorama visual rápido para relatório ou apresentação | Nuvem de palavras | ac_wordcloud() (ggwordcloud) |
Não é redundância. As três métricas de frequência respondem perguntas diferentes:
Para descobrir tipologias emergentes sem categoria a priori, veja
vignette("cluster") e vignette("lda") (não
supervisionado). Para rotular com categorias teóricas, veja
vignette("qualitativo-llm") (assistido).
O ac_corpus() padroniza qualquer data.frame
em um objeto com colunas fixas doc_id e text,
mantendo os metadados que você quiser preservar para comparações
posteriores.
textos <- c(
"O governo anunciou nova politica fiscal para reduzir o deficit publico.",
"A oposicao critica o aumento dos gastos e da divida publica no orcamento.",
"Parlamentares debatem a reforma tributaria e o imposto de renda das familias.",
"O presidente vetou o projeto que ampliava beneficios sociais para os pobres.",
"O Senado aprovou o marco legal para investimentos em infraestrutura logistica.",
"Deputados votam pela reducao da carga tributaria para pequenas empresas.",
"A politica monetaria do Banco Central eleva a taxa de juros para conter inflacao.",
"A inflacao acima da meta preocupa economistas e o mercado financeiro.",
"O relator defendeu emendas ao texto do orcamento com foco em saude e educacao.",
"A comissao aprovou o projeto que amplia beneficios sociais no interior.",
"O ministro afirmou que a reforma tributaria simplifica o sistema para empresas.",
"Lideres da oposicao pediram vistas ao projeto na comissao de constituicao."
)
meta <- data.frame(
text = textos,
tema = c("fiscal","fiscal","tributario","social","infraestrutura",
"tributario","monetario","monetario","fiscal","social",
"tributario","fiscal"),
stringsAsFactors = FALSE
)
corpus <- ac_corpus(meta)
corpus
#>
#> ── Corpus acR ──────────────────────────────────────────────────────────────────
#> • Documentos: 12
#> • Metadados: 1 coluna
#> • Idioma: "pt"
#>
#> # A tibble: 12 × 3
#> doc_id text tema
#> <chr> <chr> <chr>
#> 1 doc_1 O governo anunciou nova politica fiscal para reduzir o deficit p… fisc…
#> 2 doc_2 A oposicao critica o aumento dos gastos e da divida publica no o… fisc…
#> 3 doc_3 Parlamentares debatem a reforma tributaria e o imposto de renda … trib…
#> 4 doc_4 O presidente vetou o projeto que ampliava beneficios sociais par… soci…
#> 5 doc_5 O Senado aprovou o marco legal para investimentos em infraestrut… infr…
#> 6 doc_6 Deputados votam pela reducao da carga tributaria para pequenas e… trib…
#> # ℹ 6 more rowsSem remoção de stopwords, os termos mais frequentes de
qualquer corpus em português são artigos, preposições e conjunções
(o, a, de, que,
para…). Eles carregam pouquíssima informação temática e
sufocam qualquer padrão real de vocabulário. A regra prática em análise
de conteúdo (Sampaio & Lycarião, 2021) é sempre remover
stopwords antes de contar frequências ou calcular
distintividade.
O ac_clean() aceita o parâmetro
remove_stopwords = "pt" para aplicar uma lista de
stopwords portuguesas curada. Você pode adicionar seu próprio
glossário via extra_stopwords.
corpus_limpo <- ac_clean(
corpus,
remove_stopwords = "pt",
extra_stopwords = c("pra", "pro") # opcional: coloquiais
)
corpus_limpo
#>
#> ── Corpus acR ──────────────────────────────────────────────────────────────────
#> • Documentos: 12
#> • Metadados: 1 coluna
#> • Idioma: "pt"
#>
#> # A tibble: 12 × 3
#> doc_id text tema
#> <chr> <chr> <chr>
#> 1 doc_1 governo anunciou nova politica fiscal reduzir deficit publico fisc…
#> 2 doc_2 oposicao critica aumento gastos divida publica orcamento fisc…
#> 3 doc_3 parlamentares debatem reforma tributaria imposto renda familias trib…
#> 4 doc_4 presidente vetou projeto ampliava beneficios sociais pobres soci…
#> 5 doc_5 senado aprovou marco legal investimentos infraestrutura logistica infr…
#> 6 doc_6 deputados votam reducao carga tributaria pequenas empresas trib…
#> # ℹ 6 more rowsac_tokenize() quebra cada documento em unidades de
análise. Com n = 1L são unigramas (palavras); com
n = 2L, bigramas (“reforma tributária”). Bigramas são úteis
quando você quer capturar expressões compostas que
perdem sentido tokenizadas separadamente.
tokens <- ac_tokenize(corpus_limpo, n = 1L)
head(tokens, 12)
#> # A tibble: 12 × 3
#> doc_id token_id token
#> <chr> <int> <chr>
#> 1 doc_1 1 governo
#> 2 doc_1 2 anunciou
#> 3 doc_1 3 nova
#> 4 doc_1 4 politica
#> 5 doc_1 5 fiscal
#> 6 doc_1 6 reduzir
#> 7 doc_1 7 deficit
#> 8 doc_1 8 publico
#> 9 doc_2 1 oposicao
#> 10 doc_2 2 critica
#> 11 doc_2 3 aumento
#> 12 doc_2 4 gastosContagem de ocorrências por documento e depois agregação.
ac_count() já retorna no formato tidy pronto para
pipeline com dplyr e ggplot2.
contagem <- ac_count(corpus_limpo)
contagem
#> # A tibble: 88 × 3
#> doc_id token n
#> <chr> <chr> <int>
#> 1 doc_1 anunciou 1
#> 2 doc_1 deficit 1
#> 3 doc_1 fiscal 1
#> 4 doc_1 governo 1
#> 5 doc_1 nova 1
#> 6 doc_1 politica 1
#> 7 doc_1 publico 1
#> 8 doc_1 reduzir 1
#> 9 doc_10 amplia 1
#> 10 doc_10 aprovou 1
#> # ℹ 78 more rowsO gráfico abaixo mostra as 15 palavras mais frequentes — agora, com stopwords removidas, é possível ler os temas dominantes: reforma, projeto, tributária, orçamento, etc.
top <- ac_top_terms(contagem, n = 15)
ac_plot_top_terms(top) +
ggplot2::labs(
title = "Termos mais frequentes no corpus",
subtitle = "Discursos legislativos - 12 documentos fabricados",
caption = "acR - vignette Analise Quantitativa"
)Uma nuvem funciona como panorama visual rápido, útil para relatórios e apresentações. Não substitui análise numérica: o tamanho da palavra é proporcional à frequência, mas a posição no plot é aleatória.
Desde a versão 0.3.1 o ac_wordcloud() prefere
automaticamente o motor ggwordcloud (retorna um
ggplot, com tipografia mais legível e layout consistente
com o tema do pacote); se ele não estiver instalado, cai para o
wordcloud clássico. Você pode forçar via
backend = "ggwordcloud" ou
backend = "wordcloud".
ac_wordcloud(contagem, max_words = 40, title = "Panorama do corpus")
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.Quando o corpus tem uma variável de agrupamento (partido, período, tema, etc.), a nuvem comparativa mostra lado a lado os termos mais distintivos de cada grupo — pontuados por TF-IDF calculado tratando cada grupo como um “documento”. Aceita 2, 3 ou mais grupos.
# Nosso corpus tem 5 temas distintos — todos entram na comparativa:
ac_plot_wordcloud_comparative(
corpus,
group = tema,
max_words = 25,
title = "Termos distintivos por tema"
)
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.
#> Warning in wordcloud_boxes(data_points = points_valid_first, boxes = boxes, :
#> Some words could not fit on page. They have been removed.O layout usa ggwordcloud com facets quando disponível
(backend = "auto"), e cai em geom_text com
jitter reproduzível quando não. A semente do posicionamento é controlada
por seed = 42L. Cores vêm de ac_palette() por
padrão — uma por grupo.
Frequência bruta favorece palavras que aparecem em quase todos os documentos (mesmo depois de stopwords). O TF-IDF (term frequency × inverse document frequency) penaliza termos comuns e destaca vocabulário próprio de cada grupo — útil quando o corpus é composto por textos com propostas ou temas distintos.
Com 12 discursos curtos e cada palavra aparecendo em 1–2 documentos, o TF-IDF por documento resulta em barras quase todas iguais (todo termo único vale o mesmo). O padrão fica mais legível agregando por tema: tratamos cada tema como um “documento” e o TF-IDF revela o vocabulário característico de cada eixo temático do corpus.
freq_tema <- ac_count(corpus_limpo, by = "tema")
tfidf_tema <- ac_tf_idf(freq_tema, by = "tema")
ac_plot_tf_idf(tfidf_tema, by = "tema", n = 6) +
ggplot2::labs(
title = "Termos mais distintivos por tema (TF-IDF)",
subtitle = "Cada eixo temático como um documento; alta pontuação = termo característico do tema"
)Enquanto TF-IDF compara documento vs. corpus, keyness compara grupos — e o critério que define o grupo é seu, não do pacote. Pode ser partido, período histórico, tema, região, autor, condição experimental, faixa etária, qualquer variável categórica no seu corpus. É a métrica clássica para a pergunta comparativa: “o que um grupo diz que o outro não diz?”.
Aqui comparamos os temas fiscal e tributário — quais palavras marcam cada lado?
freq_tema <- ac_count(corpus_limpo, by = "tema")
freq_2grupos <- freq_tema[freq_tema$tema %in% c("fiscal", "tributario"), ]
kn <- ac_keyness(freq_2grupos, group = "tema", target = "fiscal")
ac_plot_keyness(kn, n = 10) +
ggplot2::labs(
title = "Palavras distintivas: 'fiscal' vs. 'tributario'",
subtitle = "Barras positivas = distintivas do tema 'fiscal'"
)Interpretação: chi-quadrado alto indica sobre-representação estatística. Termos como deficit e orçamento marcam o eixo fiscal; carga e renda o tributário — resultado consistente com o corpus de exemplo.
Palavras que aparecem próximas com frequência formam agrupamentos semânticos. A rede de coocorrência mostra essas vizinhanças com base numa janela de tokens (aqui, 5 palavras à esquerda e à direita).
Útil para: identificar frames, mapear associações conceituais e encontrar combinações de palavras que definem sub-temas dentro do corpus.
cooc <- ac_cooccurrence(corpus_limpo, window = 5L, min_count = 2L)
if (requireNamespace("ggraph", quietly = TRUE)) {
ac_plot_cooccurrence(cooc, top_n = 25) +
ggplot2::labs(
title = "Rede de coocorrencia (janela = 5, freq minima = 2)",
subtitle = "Arestas conectam termos que co-ocorrem no mesmo contexto"
)
}A rede padrão pondera arestas pela contagem de coocorrências — termos frequentes tendem a dominar. O PMI (pointwise mutual information) mede o quanto duas palavras aparecem juntas acima do esperado por acaso; revela pares surpreendentes, mesmo que raros.
if (requireNamespace("ggraph", quietly = TRUE)) {
ac_plot_cooccurrence(cooc, top_n = 25, weight = "pmi") +
ggplot2::labs(
title = "Rede de coocorrencia ponderada por PMI",
subtitle = "Destaca pares associados alem do esperado por acaso"
)
}O layout controla como os nós são posicionados no plano. O padrão
"fr" (Fruchterman-Reingold) minimiza cruzamentos;
"kk" (Kamada-Kawai) respeita distâncias de grafo;
"circle" alinha tudo num anel — útil para corpora pequenos
onde a topologia importa menos que a legibilidade.
if (requireNamespace("ggraph", quietly = TRUE)) {
ac_plot_cooccurrence(cooc, top_n = 25, layout = "circle") +
ggplot2::labs(
title = "Rede de coocorrencia — layout circular",
subtitle = "Todas as palavras num anel; arestas mostram o grafo cru"
)
}Quando a rede fica saturada de arestas, um heatmap
das top-N palavras pode ser mais legível: linhas e colunas são termos, e
a intensidade da célula é a coocorrência. Não requer
ggraph.
top_tokens <- ac_top_terms(ac_count(corpus_limpo), n = 12)$token
cooc_mat <- cooc[cooc$word1 %in% top_tokens & cooc$word2 %in% top_tokens, ]
ggplot2::ggplot(cooc_mat,
ggplot2::aes(word1, word2, fill = cooc)) +
ggplot2::geom_tile(color = "white") +
ggplot2::scale_fill_gradient(low = "#F1F5F9", high = ac_palette(1)) +
ggplot2::labs(
title = "Matriz de coocorrencia (top 12 termos)",
subtitle = "Alternativa ao grafo quando a rede fica densa",
x = NULL, y = NULL, fill = "cooc."
) +
theme_ac() +
ggplot2::theme(
axis.text.x = ggplot2::element_text(angle = 45, hjust = 1)
)These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.