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.

ocupacoesBR 0.8.2

Duas correções, sem mudança de comportamento, de dado ou de resultado: uma pedida pela revisão manual à 0.8.1, outra completando um pedido da revisão à 0.8.0 que a 0.8.1 só tinha atendido em parte.

ocupacoesBR 0.8.1

Correções pedidas pela revisão manual do CRAN à 0.8.0, sem mudança de comportamento, de dado ou de resultado.

ocupacoesBR 0.8.0

O índice de referência promete, na porta do IBGE, que “é por aqui que se compara candidatura com população”. Era a promessa mais forte do pacote e a única que ele não mostrava cumprindo — nem mostrava onde ela falha. Esta versão dá ao pacote os dois lados da comparação e a página que ensina a fazê-la.

O que motivou: em setembro de 2026 uma comparação entre candidaturas do TSE e população da PNAD Contínua foi auditada e reprovada. A tradução estava certa e os testes passaram. O erro estava numa decisão de medida que o site não desaconselhava em lugar nenhum, porque em lugar nenhum tratava do assunto — ler o primeiro dígito da ISCO-88 dos dois lados. O que reprovou a régua: os rótulos de vínculo público do formulário do TSE saem da base classificável e os mesmos trabalhadores, na PNAD Contínua, ficam dentro dela. O tamanho do viés — 3,4 pontos na classe profissional sobre uma base de 12,3 — foi medido naquela auditoria, fora deste repositório, e é citado aqui como motivo e não como número do pacote; o que este pacote mede está nas tabelas abaixo.

tse_universo: de que é feito o resíduo das candidaturas

Sete rubricas, por ano e por sexo, somando 100 dentro de cada recorte. checa_cobertura() já dizia quanto de um vetor recebe escore; esta tabela diz de que é feito o que não recebe, e mostra que a resposta muda.

Duas leituras que uma taxa de cobertura única esconde. A não declaração vai a zero a partir de 2006, o que indica campo obrigatório, e a recusa de nomear assume o lugar dela: a rubrica 999 sai de 13,5% em 1998 e chega a 21,9% em 2024. E a diferença de cobertura entre os sexos está quase toda numa linha — de 2004 em diante, Fora da força de trabalho é 1,2% das candidaturas de homens e 14,6% das de mulheres. A vinheta qual-regua já afirmava isso em prosa; agora há tabela.

cod_populacao_br: o denominador

A distribuição da população pelos endereços da ISCO-88, por piso etário de elegibilidade (18, 21, 30 e 35 anos, os da Constituição) e por sexo, com a parcela não ocupada como linha da tabela e não como ausência dela.

É decisão de escopo, tomada pelo autor com a tabela medida à vista. O pacote é um tradutor e uma distribuição populacional é outro tipo de objeto; o precedente existe nos dois sentidos (isco_posicao_br já deriva da população, tse_validacao já deriva das candidaturas) e sem ela nenhum número sobre a população seria reproduzível por quem lê. Custa 28 KB, sem indivíduo e sem identificador.

O par que ela permite calcular, e que é o eixo do artigo novo: medida sobre o mesmo universo, a cobertura do ISEI é de 61,8% na população de 18 anos ou mais e de 62,0% nas candidaturas de 2024. As duas fontes perdem quase a mesma fração de gente por motivos que não têm nada em comum — a população porque 38,0% dos adultos não estão ocupados, o Tribunal porque um em cada cinco candidatos marca uma rubrica que não nomeia ocupação. Uma taxa de cobertura parecida não é sinal de que os dois lados são comparáveis.

Ao contrário das tábuas de conversão, esta tabela envelhece, e a ajuda diz isso na primeira linha: é estimativa de amostra com peso, da PNAD Contínua de 2025, e não um censo.

isco_posicao_br ganha o setor público e a posição militar

pct_setor_publico (V4012 == 4) é a variável que faltava para medir a maior assimetria entre as duas fontes. Medido: o setor público é 11,7% dos ocupados com endereço na ISCO-88, e 37,9% dele está no grande grupo 2, professores sobretudo — a classe que carrega o argumento em quase toda análise de recrutamento.

pct_militar (V4012 == 2) sai da mesma passada e exige aviso, que está na ajuda. O dicionário do IBGE define essa posição como militar do exército, da marinha, da aeronáutica, da polícia militar ou do corpo de bombeiros militar. Medido: entre quem a declara, 39,9% cai no grande grupo 0 pelo código de ocupação e 60,1% cai no 5. A pergunta sobre posição e a pergunta sobre ocupação discordam sobre quem é militar no Brasil, e nenhuma das duas é o erro da outra.

O artigo: Comparar duas fontes

Oito decisões — a porta, a revisão da ISCO, o ano, a régua, o universo, o resíduo, a agregação e a ponte —, cada uma com o mesmo bloco de quatro partes: a decisão, o que ela permite, quem ela exclui (nomeado, e com o tamanho) e como medir esse tamanho no seu dado. Fecha com o que o pacote não faz, uma folha de decisão de uma página, e um exemplo trabalhado que roda só com dados do pacote.

Três coisas que a página mede e que não estavam ditas em lugar nenhum:

Ajuda cruzada

?cod_para_isco ganha a explicação da adaptação da polícia militar, com exemplo, e a remissão ao artigo. ?tse_para_classe ganha a seção que diz por que cod_para_classe() não existe: quatro das categorias do esquema são rubricas do formulário do TSE, não posições da ISCO, e o esquema não atravessa para a população. Quem precisa comparar composição de classe entre as duas fontes não tem régua pronta, e agora isso está dito onde a pessoa vai olhar.

Uma decisão registrada como decisão, e não como pendência

O plano previa uma função checa_comparabilidade(), que receberia dois vetores de portas diferentes e julgaria se a comparação se sustenta. Ela não foi escrita, e o motivo é bom: as quatro checa_cobertura_* existentes valem por serem triviais de entender, e um juízo de comparabilidade depende de um critério que depende da pergunta — que é justamente o que o artigo ensina o leitor a decidir. Uma função ali viraria carimbo de aprovação sobre uma decisão que ela não pode tomar. Fica registrado que foi avaliada e descartada.

O repositório abriu, e o manual voltou a compilar

O terceiro preprint saiu em 09/09/2026 — As duas faces da classe no recrutamento político brasileiro, 10.31235/osf.io/muxf8_v1 —, que era a condição para o repositório deixar de ser privado. Ele foi aberto, o GitHub Pages passou a servir https://moraespeixoto.github.io/ocupacoesBR/, e as três URLs do DESCRIPTION que respondiam 404 ao verificador anônimo do CRAN passaram a resolver. A NOTE que elas produziam em todo R CMD check --as-cran deixou de ocorrer, sem que nada no arquivo mudasse.

A faixa de publicações da home tinha dois cartões e passa a ter três, agora com DOI em todos. O cartão do artigo de método ainda dizia “manuscrito em preparação” com o DOI vazio, o que estava errado desde 04/09. E o selo “R-CMD-check passing” da home era texto fixo, que afirmava aprovação sem ler o CI: passou a ser o selo do GitHub Actions, que diz o estado do momento. O README ganhou o mesmo par, que não tinha nenhum.

Uma correção que só aparece no manual em PDF: três ocorrências do sinal de menos matemático (U+2212) numa passagem de ?tse_para_isei faziam o pdflatex parar com “Unicode character not set up for use with LaTeX”. Passaram a hífen ASCII. O leitor lê a mesma coisa; o CRAN, que constrói o manual, deixa de recusar.

ocupacoesBR 0.7.1

Uma auditoria de conteúdo do site, em quatro frentes, encontrou afirmações que o próprio pacote já contradizia. Esta versão começa a saldá-las.

O nível de habilidade 2 da ISCO-88 não vai ao pós-secundário

A aba de classificações definia o nível de habilidade 2 como indo “do secundário inferior ao pós-secundário não terciário”, num parágrafo sobre a ruptura de 1988. Essa é a definição da ISCO-08, ancorada na ISCED de 1997.

Conferido na fonte primária — ILO (1990), pp. 2-3: na ISCO-88 o segundo nível é “ISCED categories 2 and 3, comprising the first and second stages of secondary education”. O pós-secundário não terciário (ISCED-97 nível 4) só entra com a reancoragem de 2008. O texto passa a dar as quatro correspondências da ISCED-76, e a dizer que a ISCO-08 reancorou na de 1997 — precisamente porque a confusão é fácil, e o pacote está ancorado na de 1988.

A CBO tem dois tamanhos, e o site usava os dois sem avisar

A edição de 2002 traz 2.422 ocupações em 596 famílias; o domínio vigente, do Novo CAGED, traz 2.777 em 626 — e é contra ele que as taxas de cobertura do pacote são calculadas. As duas cifras conviviam em páginas diferentes sem explicação. Agora convivem com ela, e as do domínio saem de um chunk que lê o próprio arquivo de fontes.

A coluna qualidade resume duas etapas, e a segunda tem precedência

crosswalk_tse() marca "ambígua" a partir da ponte ISCO-88 → ISCO-08, e essa marca sobrepõe a informação sobre o quanto a tradução TSE → ISCO-88 foi agregada. O resultado é que códigos traduzidos exatamente, a quatro dígitos, aparecem como "ambígua" — e a ambiguidade deles é da ponte, irrelevante para quem usa o ISEI-88, que é a régua recomendada. O comportamento não muda; passa a estar dito, com a remissão a tse_isco$nivel para quem quiser só a agregação.

Outras três da mesma aba

E em vignette("qual-regua"), “as três não têm sequer o mesmo denominador” — palavra sem referente — passa a dizer o que de fato difere: população e ano de estimação.

A variância “dentro” da ocupação é zero, não “quase nada”

vignette("validacao") e ?tse_dispersao_patrimonio diziam que uma medida de posição ocupacional “explica a variância entre ocupações e quase nada da variância dentro de cada uma”. O ISEI é constante dentro da ocupação: ele explica exatamente zero, por construção, e “quase nada” sugere que se mediu algo que não é mensurável.

O que se pode medir, e diz mais, é quanto da variância individual do log do patrimônio fica entre níveis de status — o teto de qualquer função do ISEI. A vinheta passa a calculá-lo dos somatórios de tse_dispersao_patrimonio: eta² = 0,077, contra r² = 0,043 que a relação linear aproveita.

E o contraste 0,681 × 0,207 ganha a ressalva que faltava: os dois números diferem em mais coisas que o nível de agregação — um é sobre a mediana e não ponderado, o outro sobre a média do log e ponderado por candidatura. A comparação limpa, na mesma unidade e com o mesmo peso, é a correlação ecológica de 0,748 contra 0,207, agora publicada ao lado.

Três correções menores no mesmo bloco: a unidade passa a ser chamada de candidatura, não indivíduo, nos quatro lugares que ainda usavam o nome que ?tse_dispersao_patrimonio declara ter abandonado; “não use ISEI como proxy de renda individual” passa a dizer patrimônio, que é o que foi testado, com a renda por extensão; e sd_log ≈ 1,7 deixa de ser “uma ordem de grandeza” — exp(1,7) é 5,5, um fator de cinco a seis por desvio padrão, e são dois desvios que dão trinta vezes. As correlações de ?tse_validacao passam a declarar que são não ponderadas, e o 0,63 do piso a dizer que sai de data-raw/, sendo o único número daquela página que o pacote não recalcula.

Gênero: o mesmo recorte da ajuda, e o intervalo de especificações

vignette("validacao") comparava médias de ISEI por gênero sobre os 207 códigos com ISEI, enquanto ?tse_para_isei usa os 168 com n > 500. Os dois números divergiam sem que a vinheta dissesse por quê (46,1 × 47,6 lá, 46,0 × 49,0 aqui). A vinheta passa a usar o recorte da ajuda, a imprimir n, e a remeter à regressão em vez de deixar uma diferença de médias sem controle carregar o argumento.

?tse_para_isei passa a publicar o intervalo de especificações em vez do p pontual. Verificados: ponderada −6,17 (ep 3,03; p = 0,043); com erro-padrão robusto HC3, ep 4,19 e p = 0,14; sem ponderação, −5,34 e p = 0,012; com pct_mulher contínuo, −0,09 por ponto percentual e p = 0,08. O sinal e a ordem de grandeza sobrevivem a todas — o p não, e é o sinal que sustenta a advertência.

A mesma seção passa a explicitar a premissa que “viés” carrega: o ISEI pondera escolaridade e renda, e ocupações femininas rendem menos com credencial igual. A escala registra isso fielmente. É viés se o que se quer medir é credencial, e fidelidade se é retorno — a recomendação vale nos dois casos.

A assimetria de ausência é de uma classe só

vignette("qual-regua") dizia que “cerca de 15% das mulheres declaram posição fora da PEA, contra pouco mais de 1% dos homens”. Confere — mas só para a classe "Fora da PEA por posição" (códigos 581 e 931). A outra residual, "Inativo com trajetória", fica em torno de 4% nos dois sexos: quem somar as duas dilui justamente o padrão que importa. A classe passa a ser nomeada.

No mesmo parágrafo, “a vantagem feminina em status é, em boa parte, artefato disso” era uma afirmação quantitativa sem cálculo. Passa a dizer que parte pode vir daí, que a vinheta não mede quanto, e que o ponto é a comparação não ser entre iguais.

“Igualando média e desvio, a correlação some” — ela não pode somer

vignette("validacao") justificava a leitura da relocação sobre a diferença padronizada assim: a diferença bruta correlaciona-se a −0,85 com o ISEI-08, e “igualando média e desvio, a correlação some”. vignette("robustez") dizia o mesmo em forma de teste: “se a diferença fosse substantiva, essa correlação seria perto de zero”.

Ela não some, e a hipótese está invertida. Para dois vetores padronizados com correlação r, vale a identidade

cor(z1 - z2, z2) = -sqrt((1 - r) / 2)

Com r = 0,940, isso dá −0,173 — que é exatamente o valor observado, até a última casa que o computador guarda. É aritmética, não medida, e é sempre negativa: regressão à média. Com escalas idênticas e esta correlação, o residual seria −0,17 ainda que a diferença fosse inteiramente substantiva. O chunk passa a imprimir a identidade ao lado do valor observado, o que mostra o ponto melhor do que qualquer parágrafo. (De passagem: naquela unidade a correlação bruta é −0,84, não −0,85 — o −0,85 vem de ?isco08_isei_br, calculado noutra.)

A conclusão prática sobrevive inteira, e é isso que importa: padronizar remove o artefato de escala, que é grande, e sem padronizar a lista de quem sobe e desce é em boa parte a lista de quem estava embaixo. O que muda é a justificativa — e o que passa a sustentá-la é uma conferência, não uma correlação: o resíduo de uma regressão do ISEI-BR sobre o ISEI-08 é ortogonal ao ponto de partida por construção, e devolve as mesmas seis ocupações em cada ponta (idênticas e na mesma ordem entre as que sobem; as mesmas seis, com o clero mudando de lugar, entre as que descem). A leitura substantiva não depende do critério, e é isso que a autoriza.

test-isei-br.R trava as duas coisas: a concordância entre os critérios e a identidade, para que ninguém volte a ler o residual como “o artefato que sobrou”.

A prosa nomeava duas ocupações que a tabela não imprimia

No mesmo trecho, o texto dizia que entre as seis que mais descem estão “veterinário e farmacêutico”. Estão em sétimo e oitavo; a tabela imprime músico e professor de formação profissional. Corrigido, com os dois citados na posição que ocupam.

A primeira página deixa de descrever uma tabela que não é a impressa

vignette("comece-aqui") dizia “as quatro primeiras linhas” e “as três últimas”, mas a ordem de cods punha o servidor público em quinto e o comerciante — que recebe ISCO, ISEI e EGP — em sexto. A prosa descrevia uma tabela diferente da que o chunk imprimia, na página que o leitor abre primeiro. Os códigos foram reordenados, e o comerciante passa a ser nomeado.

Outras três correções na mesma página:

A recusa da CBO-94 é convenção de interface, não impossibilidade

isco08_para_isei_br(cbo94_para_isco08("2-11.20")) devolve 72 numa linha: o que o pacote retirou na 0.5.1 foi o atalho, não o caminho. A vinheta passa a mostrar o encadeamento e a dizer o que ele garante — quem escreve as duas etapas fez a escolha conscientemente.

E diz o que a razão não é. Não é adequação temporal em geral: o ISEI-88 foi estimado sobre dados de 1968 a 1982 e o pacote o aplica a candidaturas de 2026 sem objeção. A âncora ISCO-88 é escolha por consistência interna da série eleitoral, não por contemporaneidade. O critério corta num sentido só, e é melhor dizer isso que deixar o leitor supor uma regra geral de data que o pacote não segue.

O que cada porta tem para o EGP, dito porta a porta

?cbo94_para_egp afirmava: “Ao contrário do TSE, a RAIS tem essas variáveis no vínculo — vale passá-las.” Não tem. A RAIS, o CAGED e o eSocial são registros de vínculo empregatício: toda linha é um empregado. Não há conta própria nem empregador como observação, e não existe campo com o número de subordinados. Por essas portas conta_propria é FALSE por construção e o EGP sai sem IVa, IVb e V — não por omissão de quem chama, mas porque a fonte não descreve quem está fora do assalariamento. Ler a distribuição resultante como estrutura de classes do país é o erro que a ajuda agora nomeia.

Na direção oposta, ?cod_para_egp e vignette("qual-regua") diziam que com a PNAD Contínua “o esquema funciona por inteiro”. Ela vai mais longe que as outras — tem posição na ocupação e número de empregados, e com isso separa IVa de IVb, que é justamente o que fica indeterminado pela porta do TSE. Mas falta a supervisão exercida sobre assalariados, que é o que define V. Nenhuma das quatro portas do pacote a tem, como vignette("robustez") já dizia corretamente — as três páginas agora concordam entre si.

A marca que recupera a pequena burguesia é conta_propria, não proprietario

vignette("qual-regua") explicava que a pequena burguesia aparece “porque dez códigos nomeiam o proprietário no próprio rótulo e o pacote usa essa marca”. São duas marcas distintas desde 07/2026, e o EGP usa a outra: conta_propria, que tem doze códigos, contra dez de proprietario. A diferença é exatamente o agricultor e o pescador, que trabalham por conta própria — o SEMPL = 2 que o esquema exige para chegar a IVc — sem pertencerem à classe proprietária. Os dois números passam a sair de um chunk.

A reedição do cadastro é de 2002; os códigos voltam depois

Três páginas diziam que o código 214 “a partir de 2002 é escultor e pintor”. A reedição do cadastro é de 2002 — fato documental —, mas nenhum dos sete códigos reutilizados reaparece naquele ano: são 2004, 2006 e 2008. O 214 só volta, como escultor, em 2006, e há um intervalo em que aquele número não é declarado por ninguém.

A distinção não é preciosismo: é primeiro_ano_novo, e não 2002, que o corte usa (ano < primeiro_ano_novo). Uma candidatura de 2004 com o código 214 volta NA — comportamento certo, que a prosa antiga não previa. Pior: a aba de classificações imprimia a coluna primeiro_ano_novo logo abaixo de afirmar o contrário. vignette("percursos") passa a imprimir também tse_vigencia(214), e test-rotulos.R trava a concordância entre as duas tabelas.

Não há ano seguro para começar a série

vignette("qual-regua") recomendava “começar a série em 2004, ou declarar a descontinuidade”, sem dizer por que 2004. O dado não apoia a escolha: de 2002 para 2004 nada se extingue, mas de 2004 para 2006 três códigos somem e treze trocam de rótulo, e dois reutilizados só reaparecem em 2006 e 2008. A recomendação passa a ser a que se sustenta — declarar a descontinuidade e passar o ano, que resolve os reutilizados código a código —, com os tse_diff_cadastro() impressos para o leitor conferir.

No mesmo parágrafo, as contagens da troca de inventário (13 extintos, 122 criados) passam a sair de um chunk em vez da digitação. As duas participações são o único par de números daquela vinheta que o pacote não recalcula sozinho — tse_ocupacao_rotulos traz n por vigência, não por ano —, e agora dizem de onde vêm: data-raw/11_confere_retrospectivo.R, que ganhou o bloco que as calcula. Recalculadas na microbase, são 12,4% (confere) e 33,1%; a vinheta dizia 33,2%.

A etapa autoral do pacote entra no site

A tradução do cadastro do TSE para a ISCO-88 é a única do pacote sem documento externo que a confirme — a OIT publica a ponte, o MTE publica a tábua da CBO, o IBGE publica a da COD, e esta é autoral. Era também a única que vignette( "percursos") não percorria, embora R/crosswalk.R já registrasse, num comentário de código, que “o erro de medida resultante não é ruído: é heterocedástico e correlacionado com o estrato”.

A vinheta ganha uma seção que mede isso em vez de afirmá-lo. Os 258 códigos do TSE com ISCO chegam a 42 valores distintos de ISCO-88 e 29 de ISEI, e a compressão não é uniforme: o refinamento a quatro dígitos alcança 12 dos 88 códigos da classe alta e nenhum dos 101 das classes populares.

A consequência prática está dita com o alcance que ela tem, e não maior: comparações dentro das classes populares apoiam-se em escores mais agregados que as feitas dentro da classe alta, e diferenças finas no fundo da distribuição merecem menos confiança que as mesmas diferenças no topo. Não é razão para não usar a medida — é razão para não ler fino onde a tradução foi grossa.

A escada da CBO: os números e a causa estavam errados

A vinheta dizia: “Quarenta códigos que a tradução direta não resolve, e a escada resolve trinta e três. Os sete restantes continuam NA, porque nem o prefixo de dois dígitos está na tábua.”

São quarenta entradas, mas dezesseis códigos distintos; os sete NA são um código só, 142399, repetido. E a razão é outra: a família 1423 está na tábua, e cbo2002_para_isco("1423") devolve "2419". O que falta é ancestral comum na ISCO — as ocupações de 1423 se espalham por 1233, 1234, 1239 e 2419.

Corrigir isso expôs uma consequência que não estava declarada em lugar nenhum: a escada e a consulta por família aplicam regras diferentes à mesma família. Quatro dígitos consultam a moda; seis dígitos com escada = TRUE exigem ancestral comum. Em oito famílias as duas divergem, e a escada é a mais conservadora. A divergência é deliberada, mas quem alterna entre as duas entradas precisa saber que elas não respondem a mesma pergunta. Passa a estar em ?cbo2002_para_isco, na vinheta, e travada em test-cbo.R — inclusive quais são as oito.

A ponte diz agora qual destino escolhe

?isco88_para_isco08 já explicava que a sintaxe do ISMF guarda as alternativas na parte decimal e manda truncá-la; a vinheta falava em “destino escolhido” sem dizer por quem nem como. Passa a dizer, e a tirar a consequência: como o destino é sempre o mesmo para um dado código de origem, o desvio é sistemático e não se cancela ao agregar.

Mudança de comportamento: o ano na posição errada agora falha

tse_para_isei(cod, ano) aceita o ano na segunda posição. Em tse_para_classe() a segunda é superior, e em tse_para_egp() é conta_propria. Quem escrevesse tse_para_classe(cod, ano_vec) por analogia não recebia erro nenhum: as.logical(2000) é TRUE, então o ano virava a marca ligada em toda linha, e a coluna saía errada em silêncio. Era o único engano de chamada do pacote que produzia número plausível sem aviso — e vignette("comece-aqui") chegava a dizer que bastava trocar o nome da função “e o comportamento é o mesmo”, o que só vale com ano nomeado.

A correção é uma guarda de valor, não de posição: superior e conta_propria passam a recusar numérico fora de {0, 1}, e a mensagem diz onde o ano cabe. Reordenar os argumentos quebraria chamadas posicionais legítimas e o contrato já documentado; o único código que passa a falhar é o que já estava errado.

tse_para_classe(c(298, 298), c(2000, 2020))
#> Erro: `superior` deve ser lógico (ou 0/1); recebeu 2000, 2020.
#>   Isso parece ser o ano. Ele existe, mas em outra posição: passe-o
#>   nomeado, `ano = `.

A sugestão do ano só aparece quando os valores têm cara de ano; fora disso a recusa é a mesma, sem palpite. 0, 1, lógico e NA seguem valendo, e superior = NA continua sem virar “médio ou menos”.

A guarda roda antes do aviso de EGP incompleto. Avisar primeiro e falhar depois deixava no console um aviso descrevendo um cálculo que nunca aconteceu.

Os números da ajuda passam a ser conferidos contra as tabelas

A regra do projeto — nenhum valor entra em .Rd, NEWS ou vinheta sem ter saído de execução própria — cobre o momento em que o número é escrito. Não cobre o depois: um valor correto no dia em que foi digitado continua na página de ajuda quando a tabela de onde ele veio muda.

Foi assim que ?tse_codigos_autorrotulo seguiu afirmando que a dispersão de patrimônio é “de 80 vezes (p90/p10) entre os que declaram empresário, mas de 47 entre os advogados e 54 entre os comerciantes”. São os valores da agregação que somava cada bem duas vezes, corrigida em 09/2026. Os certos são 76, 48 e 55, e ?tse_para_componente_alta já os lia da tabela desde aquela correção — este parágrafo é que tinha ficado para trás.

Corrigido, o argumento fica mais forte do que era: o comerciante (55) é autorrótulo e cai entre o advogado ancorado (48) e o empresário (76). A dispersão bruta realmente não separa os dois grupos, que é o que o parágrafo sempre quis dizer.

tests/testthat/test-numeros-doc.R é a trava geral. Ele não guarda os valores: recomputa das tabelas e confere contra o texto da ajuda, de modo que o que reprova é a divergência entre os dois. Cobre por ora a dispersão por autorrótulo, os quantis do 257, a regressão de gênero de ?tse_para_isei (n, coeficiente e as duas médias) e a parcela mediada de ?isco08_isei_br. Um dos blocos trava também a ordem advogado < comerciante < empresário, porque é dela que o parágrafo depende: se ela inverter, o texto passa a afirmar o contrário do que o dado mostra, sem que número nenhum fique errado.

O Brasil estava no ISEI-88, e a justificativa do ISEI-BR dizia que não

A documentação afirmava, em quatro lugares, que Ganzeboom, De Graaf e Treiman (1992) escalonaram a ISCO sobre “dezesseis países, nenhum deles o Brasil” — e que o ISEI-BR respondia a como o Brasil ordena as ocupações “em vez da média de dezesseis países ricos”. As duas metades são falsas, e o artigo original desmente as duas.

O Apêndice A de Ganzeboom, De Graaf e Treiman (1992), sob o título 31 Data Sets Used to Construct the ISEI Scale, lista a PNAD de 1973 (BRA73, 6.697 casos) e a de 1982 (BRA82, 8.742). São 15.439 dos 73.901 homens da amostra de estimação: 20,9%, a segunda maior contribuição nacional, atrás só da norte-americana. E os dezesseis países não são ricos — o artigo descreve a amostra como indo “de países severamente subdesenvolvidos (Índia) ao mais desenvolvido (Estados Unidos), e de regimes socialistas do Leste Europeu (Hungria) a estados sul-americanos autocráticos (Brasil)”.

A justificativa do ISEI-BR não desaba com a correção; ela fica verificável, que é o que não era. O Brasil entrou no ISEI-88 com dado de 1973 e 1982, comprimido junto com outros quinze países num único escalonamento. O que não existia é um ângulo estimado só aqui, e com dado deste século. É isso que a régua nova faz, e é isso que a documentação passa a dizer — em ?isco08_isei_br, ?tse_para_isei_br, reguas$pergunta e no cabeçalho de data-raw/09_gera_isei_br.R.

O erro não era de cálculo, e por isso nenhum teste o pegaria: era um fato bibliográfico, a única classe de afirmação do pacote que nada confere.

A enfermagem não foi promovida pela ISCO-08

Quatro páginas do site — qual-regua, validacao, a aba de classificações e ?tse_para_isei08 — explicavam o salto de 26 pontos do enfermeiro dizendo que “a ISCO-08 promoveu a enfermagem a profissão de nível superior (2221), separando-a dos técnicos (3221)”. O mecanismo é falso, e o pacote já sabia disso em dois lugares: R/tse.R e o NEWS.md da 0.6.0 dizem, corretamente, que a ISCO-88 põe a enfermagem em 2230 apesar de ser profissão universitária.

A ISCO-88 já a situava no grande grupo 2, e já a separava da enfermagem técnica (3231). O que ela fazia era pontuá-la em 43, abaixo dos escriturários (45). O que muda de uma âncora para a outra é a escala: o ISEI-08, reestimado por Ganzeboom sobre o ISSP de 2002-2007 e cobrindo os dois sexos, a põe em 68,7. A recomendação de ancorar na ISCO-08 para análise de gênero continua valendo — o que muda é a razão dela, que é de escore e não de alocação.

Dois efeitos colaterais da versão antiga também saem. O primeiro é que 2221 é médico na ISCO-88 e enfermeiro na ISCO-08: o texto citava um código de quatro dígitos sem dizer de qual classificação, num pacote cuja tese é que código não sobrevive à troca de versão. Os códigos passam a vir com a âncora nomeada. O segundo é que o destino que o pacote de fato atribui ao 113 é o agregado 2220, não 2221.

A aba de classificações precisava de um exemplo de promoção 3 → 2 na fronteira entre profissionais e técnicos, e a enfermagem não serve. Passa a usar os dois casos reais, que são os mesmos do artigo de método: a fisioterapia (3226 → 2264) e a nutrição (3223 → 2265).

tests/testthat/test-isco08-tse.R ganhou dois blocos que travam os fatos que desmentem a versão antiga, para que ela não volte por cópia.

Valle Silva é da tradição de Duncan, e Ganzeboom o usou para aferir o ISEI

A aba de antecedentes dizia que Posição social das ocupações (IBGE, 1974) era “trabalho contemporâneo da própria tradição de Duncan, e não derivado dela”. Não é o que o próprio texto de 1974 diz: Duncan (1961) é a referência nº 14 da bibliografia, o procedimento do SEI é descrito em detalhe, e a escala brasileira é aferida contra as de Blishen e Bogue.

A recíproca é o achado que valia a checagem: quando Ganzeboom, De Graaf e Treiman construíram o ISEI, foi a escala de Valle Silva que serviu de termo de comparação brasileiro, e ela está na bibliografia deles. A linhagem brasileira não foi paralela à internacional — foi o parâmetro contra o qual a internacional se mediu aqui. A aba passa a dizer isso.

Autorias que estavam fundidas numa só

vignette("antecedentes") atribuía a Ganzeboom, De Graaf e Treiman a tradução da ISCO em ISEI, prestígio e EGP. São três autorias distintas: o ISEI é deles (1992), o prestígio é de Treiman (1977), o esquema de classes é de Erikson, Goldthorpe e Portocarero (1979). O que Ganzeboom e Treiman (1996) fizeram foi mapear as três sobre a ISCO-88. Pela mesma razão, Harry Ganzeboom passa a ser “um dos três autores do procedimento de 1992”, e o cartão do EGP na home deixa de dizer “sintaxes originais” — as sintaxes são a operacionalização do ISMF, não o texto de Erikson e Goldthorpe, que codificaram sobre classificações nacionais.

Correções menores na home

O cartão do ISEI dizia “10 – 90”; o intervalo do ISEI-88 é 16 a 90, e sai de reguas, não da digitação. O cartão do EGP dizia que o TSE não pergunta a posição na ocupação — o pacote a preenche pelo dicionário; o que falta, e gera o aviso, é o número de subordinados. E a chamada de qual-regua não conta mais os erros (“os sete”), porque a vinheta tem nove seções e o número envelhece calado.

ocupacoesBR 0.7.0

O pacote fica legível por quem lê máquina, e a regra que ele mais repete vira tabela.

reguas: a escolha da régua deixa de morar só na prosa

O risco central deste pacote nunca foi errar uma tradução. É trocar uma régua por outra sem perceber — a troca custa uma letra no nome da função, não produz erro nenhum, e a vinheta qual-regua abre dizendo exatamente isso. O aviso existia, mas em prosa, que é o último formato que um leitor apressado consulta.

Agora existe reguas: nove linhas, uma por medida, com a pergunta que cada uma responde, o que ela mede, de onde vem e quando não usá-la. É filtrável:

reguas[reguas$tipo == "continua", c("medida", "ancora", "funcao_tse")]
reguas$quando_nao_usar[reguas$medida == "EGP"]

Duas decisões merecem registro. A primeira é que a tabela é dado, não função: é onde a documentação do pacote já manda procurar, e onde tse_isco e tse_quebra_2002 já guardam julgamento autoral. A segunda é que ela é a única tabela do pacote que não deriva de fonte externa, e por isso fica fora da auditoria de proveniência. O que a mantém honesta é outra coisa — tests/testthat/test-reguas.R amarra as funções citadas aos exports reais nas duas direções, de modo que uma porta nova sem linha na tabela reprova o teste. Os intervalos das réguas contínuas também não são digitados: saem de isco88_medidas e irmãs no momento da geração.

A seção 1 da vinheta qual-regua passou a consumir a tabela em vez de repeti-la. Uma fonte só.

Um guia de uma página para quem lê por máquina

inst/llm/GUIA_AGENTE.md concentra o que precisa ser sabido antes da primeira chamada: a gramática <origem>_para_<destino> que 47 dos 61 exports seguem, o contrato de chamada, e as três maneiras de obter um resultado errado e silencioso — régua trocada, série longa sem ano, NA tratado como zero quando a ausência é generificada.

system.file("llm", "GUIA_AGENTE.md", package = "ocupacoesBR")

Ele remete a reguas em vez de repetir a tabela, e não é uma quarta cópia da prosa: tests/testthat/test-guia-agente.R confere que toda função citada existe, que as contagens batem com o NAMESPACE, e que o contraexemplo do guia (cbo94_para_isei_br(), a porta que deliberadamente não existe) continua não existindo.

O site parou de sabotar quem copia, e quem lê por máquina

Duas correções na home, com a mesma origem: SVG e <code> escritos à mão atravessam mal o pandoc.

A linha de instalação estava marcada como <code> com <span> de cor dentro. O pandoc lê o texto entre tags inline como markdown, e a extensão smart transformava as aspas retas de install_github("...") em aspas curvas — quem copiava do site recebia código que não roda. Agora é um bloco de código de verdade, realçado pelo próprio pandoc, com as cores devolvidas por CSS.

Os cinco ícones da home eram <svg> inline. O pandoc os converte em URI data: base64, o que enchia de lixo os espelhos .md que o pkgdown gera e o docs/llms.txt — o arquivo que modelos de linguagem leem. Os ícones viraram máscaras em CSS: o desenho é o mesmo, e o markup não os contém mais.

ocupacoesBR 0.6.0

Preparação para o CRAN, e uma aba nova no site.

O DIGCLASS sai de Suggests — e o teste fica

O DIGCLASS (Cimentada) é a única implementação independente contra a qual o EGP deste pacote é conferido. Ele não é dependência: é GPL-3, e embarcar tabela dele tornaria este pacote copyleft.

Simulando a máquina do CRAN — biblioteca sem o pacote e _R_CHECK_FORCE_SUGGESTS_ no padrão — o que aparece não é a NOTE que o cran-comments.md vinha explicando:

* checking package dependencies ... ERROR
Package suggested but not available: 'DIGCLASS'

Verificado com rede: o DIGCLASS não está em repositório algum — nem CRAN, nem Bioconductor, nem r-universe (o universo cimentadaj existe e serve só o perccalc). Logo Additional_repositories: também não resolve, porque o campo exige um repositório no formato do CRAN.

A saída preserva as duas coisas: o teste foi para tests/testthat/test-digclass.R, que está em .Rbuildignore. Ele continua no repositório, roda no devtools::test() e apareceria num CI; o pacote distribuído não menciona o DIGCLASS em lugar nenhum. Com isso o check volta a 0 ERROR, 0 WARNING, 1 NOTE, e a NOTE que sobra é “New submission” mais as URLs do repositório privado.

A referência dessa conferência estava solta

O DIGCLASS instala-se do HEAD do GitHub. A referência da única validação externa do pacote era, portanto, um ponteiro móvel: se o autor corrigisse uma célula, o teste passaria a falhar sem que se soubesse o que ele afirmava quando a validação foi feita. É o mesmo defeito que as chaves sha256 do registro de proveniência existem para impedir nas fontes.

inst/extdata/PROVENIENCIA.yml ganhou a seção conferencia_cruzada, com a versão (0.0.3), o commit e a data. 00_confere_proveniencia.R avisa quando o instalado diverge do registrado, e um teste falha se a seção sumir.

As classificações, uma a uma

Aba nova no site, entre Percursos e Antecedentes. Cada uma das quatro classificações por onde o dado entra — a ISCO, a CBO, a COD do IBGE e o cadastro do TSE — com a mesma estrutura: de onde veio, para que foi feita, e o que ela não pode responder.

A tese da página é que saber a história de uma classificação não é erudição: é o que permite prever onde ela vai falhar. Cada uma carrega no desenho a pergunta que a originou. A ISCO-88 não dá nível de habilidade aos grandes grupos 0 e 1, e por isso o primeiro dígito não é escala. A CBO ancora em 1988 e a COD em 2008, e por isso não são duas versões da mesma árvore. O cadastro do TSE não é classificação estatística: é lista de preenchimento de formulário, e daí vêm as suas quatro propriedades incômodas, da escala à reutilização de códigos.

Fecha com um quadro comparativo cuja última linha é a razão de o pacote existir: para a CBO e para a COD há tábua oficial para a ISCO; para o cadastro do TSE não há.

Os números computáveis saem de chunks; as datas e os números de resolução são digitados e vêm das fontes registradas. Onde os dois poderiam se contradizer — o tamanho da CBO contra o que o pacote cobre dela — a distinção está dita no próprio código.

Antecedentes: uma aba sobre de onde o pacote vem

O site ganhou uma página teórica, entre Percursos e Robustez. Ela declara a linhagem em que o pacote se inscreve — Valle Silva, Hasenbalg, Costa Ribeiro, Carvalhaes — e faz a subtração honesta: o que aqui é reimplementação de coisa alheia e o que é contribuição.

Três antecedentes que o pacote precisava nomear e não nomeava:

Também se registra o que não existe: nenhum dos pacotes de R que traduzem ISCO em ISEI, prestígio ou EGP cobre a CBO brasileira, e nenhum leva o cadastro do TSE a classificação alguma.

Provas de robustez, com gráficos

Aba nova no site, entre Percursos e Artigos: nove provas explicadas uma a uma — o que poderia dar errado, como se testa, o que o gráfico mostra e o que significaria se falhasse. Ida e volta entre as duas ISCO, ambiguidade preservada, conferência cruzada, critério externo, estatísticas suficientes, artefato de escala, quebra de 2002, EGP degradado e sha256 das fontes.

Nenhum número está digitado: todos saem de chunks executados sobre os dados instalados com o pacote. Três das provas existem porque o erro correspondente foi cometido e publicado aqui, e a página diz isso.

Escrever a página corrigiu duas afirmações que estavam erradas na documentação anterior. No EGP degradado são duas degradações, e não uma: IVb e IVc separam o TSE da COD, e a diferença é a marca de posição no emprego; IVa e V saem vazias nos dois, porque separá-las exige o número de subordinados, que nenhuma porta do pacote tem. E na quebra de 2002, cinco dos sete códigos reutilizados saltam na escolaridade — o 215 e o 521 quase não se movem, e no caso da governanta quem separa as duas ocupações é a composição por sexo.

Description com o DOI do método

O DESCRIPTION passa a trazer Ganzeboom, De Graaf e Treiman (1992) com <doi:10.1016/0049-089X(92)90017-B>, no formato que o CRAN pede para referência de método. O DOI foi conferido no Crossref.

ocupacoesBR 0.5.2

Auditoria geral, feita por três auditores independentes — engenharia de pacotes R e site, dados eleitorais do TSE, estratificação e medida. O pedido nasceu de uma insegurança: a 0.5.0 quebrou o pacote e teve de ser corrigida às pressas no mesmo dia, e não estava claro o que ainda restava errado.

A infraestrutura passou. R CMD check limpo, os testes passando, o site sincronizado, a proveniência conferindo por sha256, e o ISEI-BR reproduzindo dígito a dígito a partir da PNAD. O que não passou foi a documentação de números: valores que ficaram para trás quando a fonte mudou, e uma divergência real entre duas funções exportadas.

Nenhuma dessas correções muda uma conclusão do pacote. Quase todas mudam números que ele publica.

A correção do patrimônio dobrado estava incompleta

A 0.4.0 trocou a microbase porque a anterior somava cada bem duas vezes. A tabela de patrimônio do código 257 em ?tse_para_componente_alta não foi revisitada, e continuou publicando o dobro por mais duas versões. Vereador R$ 370.000 onde são R$ 185.000; prefeito R$ 1.628.485 onde são R$ 812.544; senador R$ 9.345.553 onde são R$ 4.678.498.

O argumento não muda — o fator de 25 entre vereador e senador é o mesmo, e a razão entre os extremos continua na casa das dezenas. Mudam os reais.

A causa é a mesma que o NEWS 0.3.1 já tinha diagnosticado: “o número era extraído, o verbo era digitado”. Por isso a correção não é digitar os valores certos. tse_autorrotulo_patrimonio é novo e publica os quantis de patrimônio por código e cargo para os dez códigos de tse_codigos_autorrotulo, mais o 131 (ADVOGADO) como contraexemplo ancorado. A documentação e a vinheta qual-regua agora leem a tabela. Uma próxima troca de fonte se propaga sozinha.

De quebra, a tabela mostra o contraste melhor do que a prosa mostrava: na linha agregada, o ADVOGADO tem a menor razão entre p90 e p10 de todos os códigos (47,8), e os autodeclarados vão de 55,1 a 75,6.

crosswalk_tse() e tse_para_egp() discordavam

A tabela usava a marca proprietario onde a função usa conta_propria. As duas são distintas desde 07/2026, e o crosswalk ficou de fora daquela decisão: o agricultor (601) e o pescador (604) saíam em VIIb ali e em IVc aqui.

Como ?crosswalk_tse manda publicar essa tabela como material suplementar de artigo, o suplemento contradizia o código que produziu as estimativas — e justamente na distinção que Carvalhaes (2015) aponta como o teste do EGP no Brasil. Um teste novo trava as duas saídas juntas, porque nenhum R CMD check pega divergência entre duas funções que rodam sem erro.

A mesma afirmação errada estava em ?tse_para_egp, que dizia ser proprietario o SEMPL = 2 do ISMF. É conta_propria.

?tse_para_isei08 publicava a regressão de duas versões atrás

Os coeficientes 1,212 e -9,80 são anteriores a .corrige_isco08_tse(), que entrou na 0.2.1. Os atuais são 1,266 e -12,72, com r = 0,97.

A comparação entre o ISEI-BR e o ISEI-08 estava contaminada pela escala

A 0.5.0 lia a diferença bruta isei_br - isei08 como relocação substantiva: sobem os manuais, descem os credenciados. As duas escalas não têm a mesma dispersão — o ISEI-BR sai de um min–max e tem desvio padrão 14,3 contra 21,1 —, e numa escala mais estreita o topo cai e a base sobe por aritmética. A diferença bruta correlaciona-se a -0,847 com o próprio ISEI-08.

Padronizando antes de subtrair, a correlação cai para -0,17. Sobrevive a alta da segurança pública e a queda das artísticas, do clero e das liberais da saúde. Não sobrevive a outra metade: igualadas as escalas, entram entre as maiores altas o diretor de empresas, o médico e o professor de ensino superior.

A escala não foi alterada. A recomendação inicial era reescalar para 16–90, mas a conta mostra que isso piora a compressão — a faixa fica mais estreita, não mais larga. O que muda é a leitura: vignette("validacao") passou a padronizar antes de comparar, e ?isco08_isei_br ganhou a ressalva de que a diagonal de 45 graus marca igualdade de escore e não de posição. Para quem usa o ISEI-BR sozinho, que é o uso previsto, nada disso importa: a escala é monotônica.

tse_validacao não respeitava a vigência dos códigos reutilizados

Sete códigos foram reaproveitados para ocupação diferente depois de 2002. O conjunto os agregava sobre a série inteira, misturando duas populações: o 214 saía com 30,6% de ensino superior porque metade da massa era DELEGADO DE POLÍCIA, quando ESCULTOR E PINTOR tem 2,3%; o 521 saía com 42,3% de mulheres onde a GOVERNANTA tem 97,2%.

O pacote manda o usuário passar ano = justamente para impedir isso, e não passava em casa. Agora cada um desses códigos entra a partir do seu primeiro_ano_novo. Um deles deixou de alcançar o piso de 200 candidaturas dentro da própria vigência: são 220 linhas, e não 221.

As correlações agregadas não se movem de forma perceptível (escolaridade r = 0,765; patrimônio r = 0,681). A regressão de gênero de ?tse_para_isei passa de 170 para 168 códigos, e o coeficiente de -6,14 para -6,17.

tse_quebra_2002$n_ate_2000 contava só uma eleição

A coluna diz “candidaturas com esse código até 2000”, que é a soma de 1998 e 2000, e trazia apenas 2000. O total dos reutilizados sobe de 1.628 para 1.755. O objeto chegava a se contradizer: documentava 52.090 para o 601 e carregava 51.953 na coluna.

Números que a troca de microbase deixou para trás

?isei_retrospectivo afirmava 680.317 pares consecutivos (são 684.179), 52,1% de mudança de código (52,2%) e 45,3% de mudança de escore (45,2%); a cobertura feminina vai a 58,8%. ?tse_quebra_2002 descontava uma tendência de +7,8 pp que hoje é +7,6.

Também esses estavam só digitados. data-raw/11_confere_retrospectivo.R é novo, não grava nada e imprime todos eles, medindo a defasagem e a cobertura com a própria isei_retrospectivo() em vez de reimplementá-la.

O EGP dos crosswalks sai degradado, e agora está dito

crosswalk_cod(), crosswalk_cbo2002() e crosswalk_cbo94() calculam o EGP sem posição no emprego nem supervisão, porque não há nenhuma das duas num código de COD ou de CBO. IVa, IVb e V saem estruturalmente vazias — a pequena burguesia contada como classe de serviço, que é inversão de classe e não arredondamento. Nenhum dos quatro .Rd dizia isso. Os quatro passam a dizer, e ?crosswalk_cod aponta isco_posicao_br como prior empírico disponível.

A única validação externa apontava para um alvo móvel

O DIGCLASS (Cimentada) é a única implementação independente contra a qual R/egp.R é conferido: os dois são portes das mesmas sintaxes do ISMF, feitos separadamente, e o teste compara as oito células da grade posição no emprego x supervisão. Todos os outros testes conferem o pacote contra si mesmo ou contra a fonte que ele próprio leu.

Só que o DIGCLASS não vem de repositório versionado — instala-se do HEAD do GitHub. A referência da conferência era, portanto, um ponteiro móvel: se o autor corrigisse uma célula, o teste passaria a falhar sem que se soubesse o que ele afirmava quando a validação foi feita. É exatamente o defeito que as chaves sha256 do registro de proveniência existem para impedir nas fontes, e que a auditoria acabara de fechar nos números digitados.

inst/extdata/PROVENIENCIA.yml ganhou a seção conferencia_cruzada, com a versão (0.0.3), o commit e a data. 00_confere_proveniencia.R avisa quando o instalado diverge do registrado, e um teste novo falha se a seção sumir ou se a versão mudar sem que o registro acompanhe. Congelar a tabela do DIGCLASS como fixture, que seria o modo óbvio de fixar a referência, está fechado por licença: ele é GPL-3, e embarcá-lo tornaria este pacote copyleft.

Correções menores

ocupacoesBR 0.5.1

Fecha as pontas soltas da 0.5.0, no mesmo dia. Nenhum escore mudou: os 590 valores de isco08_isei_br saem idênticos aos da 0.5.0.

cbo94_para_isei_br() foi retirada

Ela não deveria ter sido criada. O pacote recusa, e documenta que recusa, pendurar medidas ancoradas na ISCO-08 em microdado da CBO-94, e a função atravessava exatamente essa fronteira. O argumento decisivo não é a coerência com o texto, é a data: a CBO-94 é microdado anterior a 2003, e o ISEI-BR é uma régua de 2025 que a própria documentação declara ser de um ano só e não formar série. Oferecê-la a dado dos anos 1990 contradiz o que ela afirma sobre si.

De passagem, a razão que o pacote alegava para a recusa estava imprecisa desde antes. Ele dizia que a assimetria era da tábua de conversão, mas a tradução até a ISCO-08 existe e é exportada em cbo94_para_isco08(). O que se recusa é pendurar escore naquele caminho, e isso é decisão do pacote. ?cbo94_isco88 e vignette("comece-aqui") passam a dizer isso.

Os números da sensibilidade agora se refazem

A 0.5.0 afirmava, no NEWS e em ?isco08_isei_br, que sete especificações alternativas foram testadas e nenhuma move o ordenamento abaixo de 0,99. Era verdade, mas o script que produzia esses números não estava no repositório, o que é exatamente o que a proveniência deste pacote existe para impedir. data-raw/09b_sensibilidade_isei_br.R os reproduz e imprime a tabela inteira.

O tamanho da amostra viaja com a tabela

isco08_isei_br ganha os atributos n_obs e n_pessoas, com a amostra de estimação. Eles não se recuperavam das colunas, porque n_obs por linha conta a subárvore daquela célula e não a amostra que estimou o ângulo, e por isso existiam só digitados na documentação.

Citar o ISEI-BR

O pacote dizia, em quatro lugares, ser o veículo e não a fonte das réguas. Para o ISEI-BR isso deixou de valer, porque a estimação é dele. inst/CITATION, a home, o README e vignette("publicacoes") passam a registrar a exceção e as três citações que ela pede: o pacote pela estimação, Ganzeboom, De Graaf e Treiman (1992) pelo método, e o IBGE pela PNAD Contínua de 2025.

Os dois diagramas

O mapa de rede ganha o nó do ISEI-BR, ligado só à ISCO-08, e a legenda passa a distinguir medida importada de medida estimada pelo pacote. O fluxograma das quatro portas ganha o mesmo nó e acrescenta cbo94_para_isei_br à lista do que deliberadamente não existe.

ocupacoesBR 0.5.0

A régua deixa de ser importada

A vinheta de validação terminava dizendo que o pacote mostrava que a medida ordena bem as ocupações, mas não que os escores estão calibrados para o Brasil, e que calibrá-los seria a melhoria de maior valor que ainda faltava. Esta versão a faz.

isco08_isei_br traz o procedimento de Ganzeboom, De Graaf e Treiman (1992) refeito do zero sobre a PNAD Contínua de 2025: 655.787 observações de 339.181 pessoas, dos quatro trimestres. Não é tradução de escala nem recalibragem do ISEI-08. É o mesmo método, estimado aqui.

O que a régua brasileira diz de diferente. Contra o ISEI-08 importado, nas 348 células apuradas em quatro dígitos, o Spearman é 0,894 e o desvio absoluto médio é 9,7 pontos numa escala de 10 a 90. Concorda o bastante para ser reconhecível e discorda o bastante para valer a pena.

Onde discorda, é preciso cuidado com a leitura, e a versão 0.5.2 corrigiu a que estava aqui. As duas escalas não têm a mesma dispersão — o ISEI-BR sai de um min–max sobre as células de estimação e tem desvio padrão 14,3 contra 21,1 do ISEI-08 —, e por isso a diferença bruta entre as duas correlaciona-se a −0,847 com o próprio ISEI-08: quem estava no topo cai e quem estava embaixo sobe, por aritmética antes de qualquer sociologia. Igualando média e desvio, essa correlação cai para −0,17 e o desvio absoluto médio, de 9,7 para 8,1.

O que sobrevive à correção: sobem a segurança pública (policial civil e militar, bombeiro) e descem as profissões artísticas, o clero e as liberais da saúde (escultor, sacerdote, cantor, veterinário, farmacêutico) — credencial alta e remuneração modesta. O que não sobrevive é a outra metade da frase: igualadas as escalas, não são as ocupações manuais que sobem. Entram entre as maiores altas o diretor de empresas, o médico e o professor de ensino superior.

A mediação não é completa, e isso é achado. O procedimento de 1992 supõe que a ocupação carrega todo o efeito da escolaridade sobre a renda e escolhe o ângulo onde o efeito direto zera. No Brasil ele não zera: para em 0,206 contra um efeito total de 0,494, de modo que a ocupação medeia 58,4%. Os outros 41,6% são escolaridade que paga dentro da mesma ocupação. Adotou-se o ângulo de mínimo e publicou-se o resíduo, nos atributos da tabela.

A decisão é segura porque o ordenamento não depende do ângulo. O Spearman entre a escala no ângulo adotado e em mais ou menos 0,15 radianos é 0,999. Sete especificações alternativas foram testadas — 40 horas, sem restrição de horas, renda-hora, rendimento efetivo, só homens como em 1992, escolaridade em categorias, idade a partir de 25 — e nenhuma move o ordenamento abaixo de 0,99 nem a parcela mediada para fora do intervalo de 57,9% a 60,1%. Quem produz esses três números é data-raw/09b_sensibilidade_isei_br.R, e é dele que eles saem cada vez que forem reafirmados.

Contra o critério externo, ela vai melhor. Nas 165 ocupações do TSE com as três réguas e os dois critérios, a correlação com o log do patrimônio declarado sobe de 0,676 (ISEI-08) para 0,716, e o Spearman de 0,708 para 0,768. Com a escolaridade dos candidatos ela vai um pouco pior, 0,736 contra 0,783, o que é esperado: o ângulo dá mais peso à renda. O patrimônio é o único dos dois que não entra na construção de régua nenhuma.

Nomes novos

Por que 590 linhas, e não 434

A ocupação declarada ao TSE é grossa, e a porta do TSE aterrissa em códigos ISCO-08 agregados de dois e três dígitos. Uma tabela só com células de quatro dígitos devolveria NA para a maioria dos candidatos. A tabela cobre então as mesmas 590 chaves de isco08_medidas, e cada agregado é apurado juntando os indivíduos da sua subárvore, não a média das médias. Dos 407 códigos de quatro dígitos, 348 têm escore próprio e 59 herdam do grupo acima por terem menos de 30 pessoas na amostra. A coluna nivel diz quais.

O que não mudou

isco08_medidas está intacta, e continua sendo a âncora internacional. Nenhuma assinatura existente mudou. Os 1.524 testes anteriores seguem passando sem alteração.

Infraestrutura

ocupacoesBR 0.4.1

O patrimônio estava dobrado, e agora não está

Todo valor de patrimônio que este pacote publicou até a 0.4.0 estava duas vezes maior que o declarado. A causa não é do pacote: a microbase de validação vinha de uma agregação de bens que somava cada bem duas vezes.

A prova. Extraído o CSV bruto do TSE de 2024 (bem_candidato_2024_AC.csv) e somados os bens candidato a candidato, das 1.206 candidaturas com bens a fonte antiga bate em 2 e a fonte nova bate em 1.206. Sobre o conjunto das 296.096 candidaturas de 2024, a razão entre as duas é exatamente 2,0 em 100% dos casos. A fonte passa a ser a microbase construída a partir de novissimos_dados_tse, cuja chave tripla de bens já está corrigida.

O que muda: todo valor absoluto em reais. A mediana do agricultor (601) vai de R$ 244.790 para R$ 122.395; o máximo das classes populares, de R$ 253.602 para R$ 126.801. Os .Rd afetados foram corrigidos.

O que NÃO muda, e é a maior parte do que o pacote afirma. Dobrar tudo é mudança de escala, e log(2x) difere de log(x) por uma constante. Logo:

Muda também media_log em tse_dispersao_patrimonio, deslocada por log(2) = 0,693 em cada nível — o que não afeta o coeficiente que a tabela existe para reproduzir, porque um deslocamento constante não move a correlação.

A microbase mudou de fonte, e ganhou linhas

data-raw/05a_microbase_2026.R passa a ler a microbase de classe_recrutamento_politico em vez da antiga de vices_do_brasil. Além da correção dos bens, a base nova vem do repositório canônico de dados do TSE e traz 12.798 candidaturas a mais nas safras de 1998 a 2024. Três colunas saíram do contrato (eleito_v1, eleito_1t, prest_contas), nenhuma consumida pela validação.

ocupacoesBR 0.4.0

O número que faltava reproduzir agora reproduz: tse_dispersao_patrimonio

O artigo de método afirma que a correlação entre status e patrimônio cai de 0,681 no nível da ocupação para 0,208 no nível do indivíduo, e que essa queda é o resultado, não um defeito: uma escala de posição ocupacional explica a variação entre ocupações e quase nada dentro de cada uma. O segundo número era o único do texto que o leitor não podia recalcular — dependia da microbase de patrimônio, que não acompanha o pacote e não vai acompanhar.

A saída não foi publicar microdado. A correlação de Pearson é função apenas de somatórios, e o ISEI é constante dentro de cada nível: basta publicar, por nível de status, o n e as somas dos logaritmos do patrimônio e dos seus quadrados. É o que a nova tabela traz — 29 linhas, 1,5 KB, nada identificável — e dela o coeficiente sai exato, não aproximado. data-raw/08_gera_dispersao.R trava essa identidade contra o microdado (abs(r_micro - r_agreg) < 1e-12), e test-fonte.R a trava contra o dado publicado.

A coluna sd_log mostra o mesmo fato de perto, e é a razão para a tabela ir além dos somatórios: dentro de um mesmo nível de status, o desvio padrão do log do patrimônio é da ordem de 1,7 — uma potência de dez. Daí a advertência de ?tse_para_isei, que agora aponta para cá: não use o ISEI como proxy de renda ou patrimônio individual.

A vinheta validacao e ?tse_para_isei passam a extrair o valor da tabela em vez de citá-lo (a ajuda dizia 0,207; o valor é 0,208).

No artigo, fora do repositório

A validação convergente ganha a análise de sensibilidade que faltava: o coeficiente com cada critério externo sob quatro especificações — todas as ocupações, sem os códigos de autorrótulo, ponderada por candidaturas e na âncora ISCO-08 — com intervalo de 95% por bootstrap. Retirar os códigos de autorrótulo eleva a correlação com o patrimônio (0,681 para 0,703), que é o sinal esperado. O artigo passa a declarar também o que o piso de duzentas candidaturas deixa de fora (50 ocupações, de ISEI médio 53,8 contra 47,4 das incluídas) e o viés de subdeclaração do patrimônio, que é correlacionado com o componente proprietário da classe alta. E ganha a primeira figura.

ocupacoesBR 0.3.1

A safra de 2026 é atualizada para a geração de 01/09/2026

A eleição de 2026 continua aberta e o TSE republica o arquivo de candidaturas duas vezes ao dia. Esta versão troca a geração fixada de 17/08/2026, 08:30 (20.506 candidaturas) pela de 01/09/2026, 12:31 (20.829 candidaturas) — 323 candidaturas a mais, todas com o mesmo tratamento de safra aberta: eleito e votos seguem NA, e o patrimônio segue fora da validação por falta do IPCA de outubro de 2026.

O achado central não muda. Dos 210 códigos observados na nova geração (211 na anterior), nenhum é inédito: seguem todos dentro dos 275 que o dicionário já cobria. tse_isco não mudou; nenhuma ponte mudou; nenhum ISEI, prestígio, EGP, classe ou estrato se deslocou de nenhum código. tse_diff_cadastro(2024, 2026) segue sem código criado (0), e os “extintos” seguem sendo artefato de safra pequena — 46 contra 2024, 48 contra 2022 (era 47).

O total de candidaturas do pacote sobe de 3.368.921 para 3.369.244. O artigo de método (paper/artigo.qmd, fora do repositório) foi atualizado para a nova geração e para as novas contagens.

Três correções apontadas por revisão externa

Duas frágeis a menos: data-raw/07_gera_posicao.R lia a PNAD de um caminho fixo de outra máquina, e passa a usar OCUPACOESBR_PNAD com fallback em ~/dados_pnad, como os scripts 05/05a; e test-rotulos.R trava que nenhum rótulo normalizado aponte para dois códigos, condição de que tse_rotulo_para_cod(exato = TRUE) depende sem dizer. O DESCRIPTION distingue agora as pontes geradas por script do dicionário TSE→ISCO-88, que é autoral.

ocupacoesBR 0.3.0

A safra de 2026 entra, e o dicionário não precisou de uma linha

Esta versão estende o pacote das 14 eleições de 1998 a 2024 para as 15 de 1998 a 2026. O resultado central é negativo, e é o mais informativo que poderia sair: o cadastro de ocupações do TSE não criou nenhum código em 2026. Os 211 códigos observados na safra são subconjunto dos 275 que o dicionário já cobria, com a mesma grafia acentuada que vigora desde 2018. tse_isco não mudou; nenhuma ponte mudou; nenhum ISEI, prestígio, EGP, classe ou estrato se deslocou de nenhum código.

Isso importa para quem usa o pacote na eleição em curso: a tradução de 2026 não é extrapolação. checa_cobertura() sobre a safra inteira passa, e um teste novo (test-rotulos.R) trava a afirmação — se uma safra futura trouxer código inédito, a suíte quebra em vez de o pacote devolver NA silencioso.

A safra é aberta, e o pacote diz isso

O prazo de registro encerrou em 15/08/2026, mas o Tribunal ainda julga e publica candidaturas. Os dados desta versão são a geração do TSE de 17/08/2026, 08:30 — 20.506 candidaturas, cerca de dois terços do volume de 2022 nos cargos proporcionais, com DS_SITUACAO_CANDIDATURA igual a #NE em toda linha e sem apuração. Nada do que o pacote extrai depende de apuração: o rótulo de um código é propriedade do cadastro, não da candidatura. Mas o n de 2026 há de crescer, e a documentação dos dados registra a geração exata para que ninguém confunda duas safras de 2026 — o TSE gera o arquivo duas vezes por dia.

Uma armadilha nova, documentada em ?tse_diff_cadastro. tse_diff_cadastro(2024, 2026) devolve 46 códigos como “extintos”. Nenhum foi extinto. A vigência se constrói do rótulo observado, e um código raro sem candidato numa safra pequena registra ausência, não revogação — 2026 é pequena duas vezes, por ser geral e por estar aberta. Trocar o par não resolve: contra 2022, que também é geral, são 47. A metade que se sustenta é a outra, “nenhum código criado”, porque um código novo apareceria ainda que uma vez só.

A fonte dos rótulos mudou de arquivo, e o N muda por duas razões

data-raw/04_gera_rotulos.R lia um .Rda agregado de 397 MB e passa a ler as safras individuais (bancos/candidaturas/candidaturas_AAAA.rds do projeto novissimos_dados_tse), quatro colunas de cada. A troca não é de estilo. O agregado se reconstrói de tempos em tempos e pode estar defasado sem que nada no arquivo o denuncie: em 17/08/2026 ele trazia 15.866 candidaturas de 2026 contra as 20.506 da safra. Ler as safras é ler a fonte, custa megabytes em vez de gigabytes, e acrescentar uma eleição passa a ser acrescentar um arquivo. OCUPACOESBR_TSE_RDA continua honrado, para quem só tenha o agregado.

Por isso o total de candidaturas sai de 3.334.269 para 3.368.921, e a diferença tem duas causas que não convém somar às cegas:

Números derivados que se moveram com a base nova, todos recomputados:

valor 0.2.1 0.3.0
candidaturas com rótulo 3.334.269 3.368.921
eleições 14 15
códigos extintos após 2000 13 (12,2%) 13 (12,4%)
códigos criados em 2002+ 122 (33,1%) 122 (33,2%)
tse_diff_cadastro(2000, 2002), criados 67 69
candidaturas do 601 em 1998–2000 50.139 52.090
reutilizados, candidaturas em 2000 1.582 1.628

Os 69 criados entre 2000 e 2002 substituem 67 porque a base recuperou uma candidatura de 2002 nos códigos 150 (CHAVEIRO) e 241 (TAPECEIRO), cuja vigência começava em 2004 e passa a começar em 2002.

O que ficou idêntico, e é o que mais importa

tse_ocupacao_rotulos continua com 334 vigências para os mesmos 275 códigos, e tse_quebra_2002 com 44 códigos na mesma partição — 15 redefinidos, 18 refinados, 4 renomeados, 7 reutilizados. A curadoria editorial do campo tipo, que é a única decisão de medida desta tabela, não se mexeu sob uma base maior e uma safra a mais. A suíte passa em 1310 expectativas, sem nenhuma alteração de valor esperado além do teto de ano.

tse_validacao vai a 2026, sem o patrimônio de 2026

A tabela do critério externo passa a somar 3.347.794 candidaturas nas mesmas 221 ocupações. A safra entra em n, pct_superior e pct_mulher, e se abstém de n_com_bens e de toda mediana de patrimônio.

A abstenção é de unidade, não de qualidade do dado. O patrimônio da tabela está deflacionado a reais de outubro de 2024, pelo número-índice do IPCA do mês da eleição, e outubro de 2026 não aconteceu. Deflacionar por outro mês poria na coluna um valor que a definição da coluna desmente. A assimetria não é nova: n sempre cobriu período mais largo do que n_com_bens, porque não há declaração de bens antes de 2006, e as candidaturas de 1998 a 2004 já entravam nessa condição. Quando o índice de outubro de 2026 existir, a coluna sai de graça.

O desenho é verificável, e foi verificado. Rodando 05_gera_validacao.R sobre as duas microbases, a safra de 2026 move exatamente o que devia mover e nada além:

efeito sum(n) sum(n_com_bens) pct_superior mediana
religação de bens (a montante) +0 +67.117 0 códigos 137 códigos
safra de 2026 +20.447 +0 108 códigos (máx. 1,5 pp) 0 códigos

A religação de bens é a segunda correção vinda de fora: a chave de junção da declaração de bens passou a ser tripla (ano, sg_ue, SQ_CANDIDATO), o que recuperou 67.117 declarações que os zeros à esquerda da unidade eleitoral faziam perder. Ela desloca 137 medianas — entre elas a do código 257, de R$ 495.400 para R$ 497.797 — e a dispersão do 257 passa de 81 para 80 vezes (p90/p10). Nenhuma dessas mudanças altera a leitura substantiva registrada em ?tse_codigos_autorrotulo: o 257 continua sendo a mistura de duas populações sob um rótulo só.

As correlações que a vinheta validacao reporta:

0.2.1 0.3.0
ISEI × % superior r = 0,764 (rho 0,811), n = 208 r = 0,765 (rho 0,812), n = 208
ISEI × log mediana de patrimônio r = 0,682 (rho 0,695), n = 164 r = 0,681 (rho 0,695), n = 165
nível do indivíduo r = 0,207 r = 0,208

A microbase que sustenta a tabela é produzida por um script novo, data-raw/05a_microbase_2026.R, que anexa 2026 às linhas de 1998 a 2024 sem recalcular nenhuma delas. A escolha é o que torna a decomposição acima possível: se as linhas antigas fossem refeitas junto, toda diferença teria duas causas e nenhuma separável.

Correção de um número que estava errado desde antes desta versão

tse_codigos_autorrotulo estava documentado como 12,2% das candidaturas (em ?tse_para_isei, ?tse_codigos_autorrotulo e na vinheta qual-regua). O valor correto é 13,3%, e o erro não vem da base nova: sobre a base antiga o valor já era 13,29%, e sobre a microbase do vices_do_brasil, 13,30%. Nenhum denominador plausível produz 12,2% — entre as candidaturas com escore ISEI o percentual é 20,7%.

A origem do engano é visível: 12,2% é o percentual dos códigos extintos sobre as candidaturas de 1998–2000, que aparece a duas seções de distância e foi copiado para a documentação do autorrótulo, que mede outra coisa. Os dois valores agora divergem também na aparência (13,3% e 12,4%), o que reduz a chance de a confusão se repetir.

Nenhum resultado publicado muda por isso: o vetor tse_codigos_autorrotulo sempre teve os mesmos dez códigos, e a análise de sensibilidade que ele serve nunca dependeu do percentual. O que muda é a frase que o descreve.

Auditoria de cobertura de testes, e os defeitos que ela encontrou

A suíte cobria 85,2% das linhas de R/. A auditoria começou por uma pergunta simples — toda função exportada é chamada ao menos uma vez? — e a resposta era não: doze das 57 não eram, entre elas as oito de R/prestigio.R, arquivo que a suíte não executava em nenhuma linha. A cobertura agora é 97,5%, com as 57 exportações exercitadas e a suíte em 1.447 expectativas (eram 1.310).

Escrever esses testes revelou três defeitos reais, e é por isso que eles valem mais do que o número de cobertura.

tse_para_prestigio08() não aceitava ano

A versão 0.2.0 acrescentou o argumento ano às portas ancoradas na ISCO-08 e nomeou três: tse_para_isco08(), tse_para_isei08() e tse_para_siops08(). Esta ficou de fora. O efeito é perverso porque *_prestigio() é o nome preferido e *_siops() o alias depreciado: durante duas versões o nome que a documentação recomenda não mascarava vigência, enquanto o desaconselhado mascarava. Quem montasse série pela porta certa recebia, sem aviso, o escore do cadastro errado nos códigos reutilizados em 2002 — exatamente o erro que o argumento existe para impedir.

Corrigido. Um teste novo compara as assinaturas dos seis pares prestigio/siops e falha se voltarem a divergir.

A família da CBO-2002 perdia empate e escada no meio do caminho

cbo2002_para_isco(), cbo2002_para_isei08(), cbo2002_para_prestigio(), cbo2002_para_prestigio08() e cbo2002_para_siops08() aceitavam os dois argumentos; cbo2002_para_isei() e cbo2002_para_siops() não. Quem ligasse a escada para obter o código ISCO e a perdesse ao pedir o ISEI terminava com duas colunas calculadas sobre universos diferentes, sem sinal de erro. As duas funções agora têm a assinatura das demais, com os mesmos padrões.

tse_rotulo_para_cod() devolvia NULL em vez de tabela vazia

Com exato = FALSE e nada a procurar — vetor vazio, ou todo NA —, do.call(rbind, ...) devolvia NULL, de modo que o tipo do retorno dependia do conteúdo do argumento: data.frame quase sempre, NULL nesses dois casos. nrow() respondia NULL em vez de 0 e o acesso a coluna errava. Agora sai sempre um data.frame, com zero linhas quando não há o que procurar. O ramo exato = TRUE nunca teve o problema.

O pacote ganha um site

A documentação passa a ter uma porta de entrada fora do R. O site é construído com pkgdown a partir do próprio repositório e será servido pelo GitHub Pages em https://moraespeixoto.github.io/ocupacoesBR/ assim que o repositório for aberto. Ele reúne o que já existia — o README, as duas vinhetas, o changelog, a citação — e acrescenta quatro coisas novas.

A referência deixou de ser alfabética. As 57 funções estão agrupadas por porta de entrada e por finalidade: a porta do TSE, o cadastro do TSE ao longo do tempo, a porta da CBO, a porta do IBGE, as medidas a partir da ISCO, a verificação de cobertura, o carregamento retrospectivo, as tabelas, e por último os alias depreciados *_siops*, com a explicação de por que foram renomeados. Ordem alfabética é útil para quem já sabe o nome da função; para quem não sabe, esconde o pacote.

Quatro artigos novos, só do site. “Comece aqui” percorre o caminho inteiro numa sessão e é construído em torno de uma tabela de oito ocupações reais e frequentes, que mostra onde o ISEI se abstém e o esquema de classes ainda responde. “Os percursos” mostra cada caminho de tradução e o ponto exato em que ele para: a ambiguidade da ponte ISCO-08, o empate e a escada da CBO, a quebra de 2002, a categoria residual. “A safra de 2026, na régua” reúne o que o pacote já sabe da eleição em curso e o que não pode saber ainda. “Como citar” explica por que são duas referências e não uma.

Os artigos vivem em vignettes/articles/, que fica fora do tarball: o site cresce sem que o pacote engorde.

Quatro fluxogramas. Escritos em mermaid e pré-renderizados para SVG por data-raw/fig_diagramas.R, de modo que funcionam offline e não dependem de script carregado de CDN. Reusam a paleta de data-raw/fig_rede_crosswalks.R, para o site não falar dois idiomas visuais. O diagrama da CBO foi redesenhado depois de conferido contra cbo2002_para_isco(): a primeira versão punha a escada antes do empate, e a ordem real é a inversa — o empate decide a entrada de quatro dígitos, e a escada só age depois, sobre o que sobrou NA.

Exemplos nas 14 tabelas de dados. Era o único ponto em que a referência estava incompleta: as 57 funções já tinham exemplo, os dados não tinham nenhum. Cada tabela ganhou um @examples que a mostra e a põe em uso — em tse_quebra_2002, os códigos reutilizados, com o 214 que era delegado de polícia e passou a ser escultor e pintor.

Duas armadilhas encontradas no caminho

O pkgdown transforma em página todo arquivo .md da raiz do repositório e de .github/, sem opção de exclusão. Aqui isso significava publicar o ferramental de assistentes de IA e os registros datados de auditoria, todos gitignorados. Apagar as páginas depois do build não resolve: o índice de busca e o sitemap guardam o texto desses arquivos. Por isso o build passa por data-raw/constroi_site.R, que os esconde antes e os devolve depois, com lista branca — arquivo de trabalho novo na raiz não vaza para o site por esquecimento.

O SVG do mermaid sai de dentro de um HTML, e o parser de HTML rebaixa todo nome de atributo para minúsculas e não fecha o <br>. Num arquivo .svg servido como XML isso quebra o desenho: viewbox não é viewBox. O extrator restaura os nomes, fecha as tags e acrescenta xml:space="preserve", sem o qual o SVG descarta o espaço inicial de cada tspan e “o código declarado” é desenhado como “ocodigodeclarado”.

O que isso mexeu no resto

A porta da CBO-2002 derrubava a chamada quando o código vinha como número

Passar à CBO-2002 um vetor numérico com dois ou mais códigos distintos de 3 ou 5 dígitos matava a chamada com the condition has length > 1. Não é caso de laboratório: é o que sai de read.csv() sobre a RAIS, onde a coluna de CBO vira integer e qualquer código malformado fica curto.

A causa está numa linha de .norm_cbo2002(): o width do formatC() vinha de um ifelse(), e formatC() não vetoriza width. Com um código curto o vetor tinha comprimento 1 e a chamada passava — o que escondeu o defeito desde que a perna CBO existe. Os dois comprimentos agora vão em chamadas separadas, cada uma com o seu width escalar.

As dez portas da CBO-2002 caíam juntas, porque todas passam pelo mesmo normalizador: as sete cbo2002_para_*, cbo2002_concordancia(), crosswalk_cbo2002() e checa_cobertura_cbo2002(). Um código malformado no meio do vetor derrubava também a tradução dos vizinhos, que estavam corretos. Agora ele volta NA com aviso, e o resto do vetor é traduzido.

A CBO-94 e a COD nunca tiveram o problema: usam width escalar.

E uma assimetria que a correção revelou

Nenhum código da CBO-2002 começa com zero — 0 de 1.387 ocupações, 0 de 436 famílias, 0 de 558 prefixos da escada. Na CBO-94 são 231 de 1.387. Ou seja: a recuperação de zero à esquerda só faz trabalho de verdade na CBO-94; na CBO-2002 ela transformava um código curto num código igualmente inexistente, com a diferença de que o aviso passava a ser “sem correspondência” em vez de “deve ter 4 ou 6 dígitos”. Um teste novo trava as três contagens: se uma tábua futura trouxer código iniciado em zero na CBO-2002, a suíte quebra e a assimetria é reexaminada em vez de suposta.

O uso normal ficou explícito logo no começo

A home do site e o artigo “Comece aqui” passam a abrir com a linha que responde à pergunta que todo mundo faz primeiro:

dados <- dados |> mutate(isei = tse_para_isei(CD_OCUPACAO, ano = ANO_ELEICAO))

A coluna inteira entra, a coluna traduzida sai, alinhada linha a linha, e o banco não muda de tamanho. Estava implícito em toda a documentação e explícito em lugar nenhum: os exemplos anteriores usavam vetores curtos como c("111", "169", "257"), que cabem na tela mas sugerem tradução código a código. A versão em R base (dados$isei <- ...) vem logo abaixo, e a junção com crosswalk_tse() fica ao lado, para quem quer as dezesseis colunas de uma vez.

O exemplo é executado, não digitado, e a moldura inclui de propósito uma linha de 1998 com o código 214. Com isso as duas formas aparecem lado a lado sobre a mesma linha: o mutate() com ano devolve NA e avisa, e a junção — que usa o cadastro corrente — devolve escultor e pintor com ISEI 54, em silêncio. A ressalva sobre ano deixa de ser uma advertência abstrata e passa a ser algo que o leitor vê acontecer.

DESCRIPTION ganha Config/Needs/website: dplyr. O dplyr não entra em Imports nem em Suggests, e o pacote continua com stats e utils como únicas dependências: ele é preciso apenas para gerar o README e o site.

Também nesta versão

ocupacoesBR 0.2.1

Correção da régua ISCO-08: 21 códigos do TSE mudam de destino

Esta versão corrige o passo TSE → ISCO-08 em 21 dos 275 códigos do dicionário, o que equivale a 103.365 candidaturas — 3,10% do total e 4,84% das que têm escore. A média ponderada do ISEI-08 passa de 49,88 para 50,43 (+0,545). O efeito substantivo é distribucional, não médio: 1,29% das candidaturas saem do primeiro decil da distribuição para perto da mediana, de modo que cortes por quantil e dicotomias “classe alta / popular” construídas a partir do ISEI-08 precisam ser recalculados, não só as médias.

Origem: auditoria da régua conduzida em 2026-08 contra a tabela oficial de correspondência da OIT (ISCO-88 → ISCO-08) e contra as sintaxes do ISMF distribuídas em inst/extdata/fontes/ganzeboom/.

O que não mudou, e por quê

Como a correção foi implementada

tse_para_isco08() deixa de ser a mera composição isco88_para_isco08(tse_para_isco(cod)). O código do TSE carrega duas informações que a ponte genérica não pode ver, e as duas são usadas agora:

  1. A marca de proprietário (tse_isco$proprietario), que é o SEMPL = 2 do ISMF;
  2. O rótulo em português, mais fino do que o código ISCO-88 agregado a que o dicionário associa aquele código.

A regra mora numa única função interna, .corrige_isco08_tse() (em R/isco08.R), chamada tanto por tse_para_isco08() quanto por crosswalk_tse() — não há duas cópias que possam divergir, e test-isco08-tse.R trava a igualdade entre as duas saídas. Como tse_para_siops08() e tse_para_prestigio08() passam por tse_para_isco08(), o SIOPS-08 desses 21 códigos também se corrige.

1. Promoção do proprietário rural (iskopromo.sps)

Os três códigos abaixo recebiam, na mesma linha do crosswalk_tse(), EGP IVc: proprietário rural, estrato “Classe alta”, componente “Alta proprietária” e o ISEI-08 de trabalhador agrícola. Eram as únicas três linhas da tabela inteira em que “Classe alta” convivia com ISEI-08 abaixo de 40 — o teste de consistência interna que a auditoria propôs isola exatamente estas três, e agora ele está na suíte.

Cód. Rótulo ISCO-08 antes ISEI-08 antes ISCO-08 agora ISEI-08 agora % cand.
234 PRODUTOR AGROPECUÁRIO 6130 17,79 1311 49,48 0,572
602 PECUARISTA 6130 17,79 1311 49,48 0,509
901 PROPRIETÁRIO DE ESTABELECIMENTO AGRÍCOLA, DA PECUÁRIA E FLORESTAL 6130 17,79 1311 49,48 0,212

Fonte. iskopromo.sps (Ganzeboom, ISMF), primeira regra do módulo, cuja finalidade declarada é “make sure that managers and owners with certain employment statuses go into the right place”:

do repeat iii=@isko / sss=@sempl.
do if (sss eq 2).          /* proprietário / conta própria com empregados */
. recode iii (6130=1311).
end if.
end repeat.

O pacote já aplicava esta linha desde 0.1.0, mas só no caminho do EGP (R/egp.R), o que é a razão de a contradição ser interna: o EGP sabia que aquela pessoa era proprietária e o ISEI-08 não. ISCO-08 1311 é Agricultural and forestry production managers; ISEI-08 = 49,48, lido de isqoisei08.sps linha 28 (recode @isqo (1311=49.48)).

A correção também remenda uma série que o TSE construiu homogênea e a tradução partia ao meio: os irmãos diretos de 901 — 902 (comercial), 903 (industrial), 904 (serviços), 905 (microempresa) — recebem todos ISEI-08 51,01, com o mesmo estrato e o mesmo componente de classe. Só o agrícola desabava para 17,79.

Recomendação da auditoria que foi REJEITADA. A auditoria propunha obter o mesmo resultado recodificando a origem, TSE → ISCO-88 de 1311 para 1221 (department managers in agriculture). Não foi feito: a codificação em 1311 é deliberada (o comentário do autor em inst/extdata/fontes/R/classe_ocupacao.R registra “PRODUTOR AGROPECUÁRIO: 61=23 → 1311=43 (proprietário rural)”), e a rota 1221 mudaria também a régua antiga, levando o ISEI-88 de 43 para 67 e deslocando resultados já publicados em ISEI-88. A promoção via iskopromo.sps chega ao mesmo ISCO-08 sem tocar em nada da ISCO-88 — e tem precedente dentro do próprio pacote.

Efeito colateral que convém declarar: para estes três códigos a ida e a volta deixam de fechar. isco08_para_isco88("1311") devolve 1221, porque a ponte de volta (isco0888.sps) também é a da OIT. A assimetria é inerente a iskopromo.sps, cuja recodificação depende do status de emprego, que a volta não conhece.

2. Destinos ISCO-08 refinados pelo rótulo do TSE

Onze códigos do TSE cujo ISCO-88 é o agregado 7400 (other craft and related trades workers) caíam em ISCO-08 7540, que é o grupo-menor residual da submajor 75 (“other craft”: mergulhadores, dinamitadores, classificadores de produtos). O ISEI-08 de 7540 (43,19) destoa em ~19 pontos de toda a sua própria família (7500 = 23,97; 7510 = 23,46; 7520 = 23,65; 7530 = 22,03). A prova de que é transposição de dígito, e não escolha, está no próprio isco8808.sps: ele manda cada ramo filho ao lugar certo — 7410=7510, 7420=7520, 7430=7530, 7440=7536, 7441=7535, 7442=7536 — e só o agregado ao residual.

Cód. Rótulo Antes Agora ISEI-08 % cand. Fonte
713 CARPINTEIRO, MARCENEIRO E ASSEMELHADOS 7540 (43,19) 7520 23,65 0,252 isco8808.sps: 7422 (marceneiros) → 7520
228 PADEIRO, CONFEITEIRO E ASSEMELHADOS 7540 (43,19) 7510 23,46 0,154 7412 (padeiros, confeiteiros) → 7510
710 TRAB. DE FABRICAÇÃO E PREPARAÇÃO DE ALIMENTOS E BEBIDAS 7540 (43,19) 7510 23,46 0,051 7410 (food processing trades) → 7510
591 ALFAIATE E COSTUREIRO 7540 (43,19) 7530 22,03 0,069 7430 (textile, garment trades) → 7530
705 TRABALHADOR DE FABRICAÇÃO DE ROUPAS 7540 (43,19) 7530 22,03 0,063 7430 → 7530
188 FIANDEIRO, TECELÃO, TINGIDOR E ASSEMELHADOS 7540 (43,19) 7530 22,03 0,005 743 (textile trades) → 7530; ver ressalva
241 TAPECEIRO 7540 (43,19) 7530 22,03 0,018 7437 (estofadores) → 7534, dentro de 753
186 ESTOFADOR 7540 (43,19) 7530 22,03 0,011 7437 → 7534, dentro de 753
149 CHAPELEIRO 7540 (43,19) 7530 22,03 0,001 7433 (tailors, dressmakers and hatters) → 7531, dentro de 753
715 TRAB. DE FABRICAÇÃO DE CALÇADOS E ARTEFATOS DE COURO 7540 (43,19) 7536 18,07 0,047 7442 (shoemakers arw) → 7536, destino único
250 TRABALHADOR DE CURTIMENTO 7540 (43,19) 7535 28,08 0,003 7441 (pelt dressers, tanners and fellmongers) → 7535, destino único

Ressalva sobre o cód. 188 (0,005% das candidaturas, n = 170). Este é o único dos onze em que a leitura fina não fecha: isco8808.sps manda 7431 (fibre preparers) para 7318 (artesanato, ISEI-08 28,97) e 7432 (weavers, knitters) para 8152 (operadores de máquina, ISEI-08 18,03) — a ISCO-08 dispersou o grupo. Como o dicionário lê este código pelo ramo artesanal (ISCO-88 74, não 82), adotou-se o grupo-menor do agregado ISCO-88 743, que é 7530. As quatro leituras possíveis ficam entre 18 e 29; nenhuma se aproxima dos 43,19 anteriores, que é o que a correção precisa garantir.

Três códigos cujo ISCO-88 é o agregado 2220 (health professionals except nursing) caíam no agregado ISCO-08 2200, que é a média de todos os profissionais de saúde, inclusive a enfermagem. Os rótulos do TSE nomeiam a ocupação exata, e para cada uma a OIT dá destino único:

Cód. Rótulo Antes Agora ISEI-08 % cand. Fonte
115 ODONTÓLOGO 2200 (76,98) 2261 (Dentists) 88,31 0,299 isco8808.sps: 2222 → 2261, único
112 VETERINÁRIO 2200 (76,98) 2250 (Veterinarians) 84,14 0,131 2223 → 2250, único
117 FARMACÊUTICO 2200 (76,98) 2262 (Pharmacists) 81,13 0,155 2224 → 2262, único

Um código cujo ISCO-88 é 2320, que tem exatamente dois destinos na OIT — 2320 (vocational education teachers) e 2330 (secondary education teachers) —, e que a ponte trunca para 2330 nos dois casos:

Cód. Rótulo Antes Agora ISEI-08 % cand. Fonte
235 PROFESSOR E INSTRUTOR DE FORMAÇÃO PROFISSIONAL 2330 (82,41) 2320 72,30 0,211 dos 2 destinos da OIT para 2320, o que o rótulo nomeia. O 2330 fica com o cód. 266, PROFESSOR DE ENSINO MÉDIO, que não muda

Três códigos cujo ISCO-88 é o agregado 3470 (artistic and cultural associate professionals), traduzido por 3430, que pressupõe nível técnico — embora os rótulos do TSE reproduzam literalmente os títulos de ISCO-88 2453 e 2454, de nível profissional:

Cód. Rótulo Antes Agora ISEI-08 % cand. Fonte
164 MÚSICO 3430 (50,15) 2652 (Musicians, singers and composers) 64,44 0,220 isco8808.sps: 2453 → 2652, único
163 CANTOR E COMPOSITOR 3430 (50,15) 2652 64,44 0,113 2453 → 2652, único
165 COREÓGRAFO E BAILARINO 3430 (50,15) 2653 (Dancers and choreographers) 61,82 0,007 2454 → 2653, único

Todos os valores de ISEI-08 acima foram lidos de inst/extdata/fontes/ganzeboom/isqoisei08.sps; nenhum foi estimado.

Onde esta versão diverge da auditoria

Pendências conhecidas, herdadas da auditoria

Nenhuma foi resolvida nesta versão; ficam anotadas para a nota de método de quem publicar a partir do pacote.

Documentação e testes

ocupacoesBR 0.2.0

tse_para_isei08() passa a aceitar ano

As portas ancoradas na ISCO-08 — tse_para_isco08(), tse_para_isei08() e tse_para_siops08() — ganharam o argumento ano, com a mesma máscara de vigência que as portas da ISCO-88 já tinham. Passando o ano da eleição, as candidaturas cujo código o TSE reutilizou em 2002 voltam NA com aviso da classe ocupacoesBR_quebra_2002, em vez de traduzidas pelo cadastro errado. Antes, quem quisesse o ISEI-08 mascarado por vigência tinha de aplicar a máscara à mão; agora é tse_para_isei08(cod, ano = ano), simétrico a tse_para_isei(cod, ano = ano). Veja ?tse_vigencia e ?checa_periodo.

Uma classe própria para o agricultor: criada e revertida (29/07/2026)

Nenhuma proporção publicada muda. O registro fica porque a decisão chegou a ser implementada, e o motivo da reversão é reaproveitável.

Correção em tse_validacao (29/07/2026)

Muda o conteúdo de um conjunto de dados publicado

Quem precisa mudar código

Segunda rodada de auditoria (27/07/2026)

Quatro revisores independentes reauditaram o estado corrigido (AUDITORIA_2026-07-27.md), rodando R sobre o dado real. A fidelidade às fontes do ISMF é byte-a-byte (zero divergências). Estas são as correções aplicadas.

Muda resultado obtido com a versão anterior

As advertências saem da vinheta e entram nas páginas de ajuda

O pacote já conhecia os seus limites e os documentava — nas vinhetas. Quem faz ?tse_para_isei, que é o caminho de quase todo usuário, não os recebia. Três seções novas, com números reproduzidos no dado real:

Correções

A medida se afere contra a PNAD

*_para_prestigio() passa a ser o nome canônico

No Brasil, SIOPS é o Sistema de Informações sobre Orçamentos Públicos em Saúde (Ministério da Saúde, LC 141/2012). Um pacote em português que exporta tse_para_siops() colide em toda busca, e a interseção de públicos — saúde, orçamento, dados administrativos — não é pequena. Ganzeboom pode usar a sigla; um pacote brasileiro não deveria, sem mais.

São oito portas: tse_para_prestigio(), tse_para_prestigio08(), isco88_para_prestigio(), cbo2002_para_prestigio(), cbo2002_para_prestigio08(), cbo94_para_prestigio(), cod_para_prestigio() e cod_para_prestigio08(). Nenhum número muda: as formas *_siops() continuam existindo como alias, verificados idênticos um a um, e não serão removidas de uma vez.

Junto vem o que faltava à régua: Treiman (1977) citado, e a advertência de que a escala é média de estudos de ~60 países dos anos 1960–70 — aplicá-la a dado recente pressupõe que a ordem de prestígio é invariante no tempo, que é a tese de Treiman e não um fato dado. Ela quebra onde a ocupação mudou de posição desde então: bancário, professor, policial, ocupações de tecnologia.


Correções da auditoria de 26/07/2026 (AUDITORIA_2026-07.md). Cinco revisores independentes varreram o pacote linha a linha rodando R sobre 3.334.269 candidaturas.

Mudanças que alteram resultado

Estas mudam números já obtidos com a versão 0.1.0. Quem publicou com ela deve reconferir.

Correções silenciosas que passaram a fazer barulho

Duas vinhetas

A porta do IBGE, e a ponte que faltava de volta

A medida passa a se aferir contra algo fora dela

Até aqui, tudo no pacote era tradução — código do TSE para ISCO, ISCO para ISEI — e nada nessa cadeia se conferia contra coisa alguma externa. Um crosswalk internamente consistente pode estar inteiramente errado.

A história do cadastro do TSE

O DS_OCUPACAO vem ao lado do CD_OCUPACAO nos arquivos consulta_cand e está 100% preenchido nas 14 eleições de 1998 a 2024. O pacote supunha não tê-lo: ?checa_periodo dizia, por escrito, “não por rótulo — o pacote não distribui os rótulos do TSE — e sim pelo dado”. A resposta exata sempre esteve na coluna ao lado.

Novidades

Infraestrutura


ocupacoesBR 0.1.0

Primeira versão. Duas portas de entrada (TSE e CBO-2002/CBO-94), 27 funções exportadas, 8 conjuntos de dados, todas as tabelas geradas por script a partir das fontes originais.

Mudança de dado registrada retroativamente: durante o desenvolvimento, o código 111 do TSE passou de ISCO-88 2220 para 2221 (e o ISEI de 85 para 88), ao descer de dois para quatro dígitos e separar médico de enfermeiro. Resultados obtidos antes dessa correção diferem. Não havia NEWS.md à época — este parágrafo existe para que a diferença seja rastreável.

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.