Este documento apresenta, de forma clara e estruturada, a metodologia aplicada ao tratamento dos dados de exportação, consumo interno (Mato Grosso) e consumo interestadual da cadeia da soja. A análise utiliza os dados disponibilizados pela SEFAZ referentes aos anos de 2023 e 2024. A seguir, é descrito passo a passo o processo de tratamento, destacando os CFOPs utilizados e as técnicas estatísticas empregadas.
1.Processo padrão para todos os casos
No primeiro passo, os dados são importados separadamente por ano e por NCM. Em seguida, são realizadas as transformações necessárias, como a conversão de colunas originalmente em formato de texto que representam valores numéricos e a remoção de valores duplicados, o ajuste de colunas de datas para o formato adequado e a junção das bases com as informações de NCM. Na sequência, é feita a classificação dos CFOPs com base no primeiro dígito, permitindo identificar a natureza de cada operação.
Code
rm(list =ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio, stringdist, scales)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2024 , NCM e juntar as basesdados_2024 =read_parquet('IMEA_2023_novo.parquet')NCM <-read_excel("NCM.xlsx")|> dplyr::filter(Produto=="Milho"|Produto=="Soja"| Produto=="Algodão em pluma") |># selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)amostra = dados #remover valores duplicadosamostra <- amostra %>%distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <-as.Date(amostra$DATA_EMISSAO_CTE, format ="%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <-as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_PRODUTO)))# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <-as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_UNIDADE_COMERCIAL)))# quantidade de cargaamostra$QTDE_CARGA <-as.numeric(gsub(",", ".", gsub("\\.", "", amostra$QTDE_CARGA)))# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO<-as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALOR_PRESTACAO_SERVICO)))classificar_cfop <-function(cfop) {# Converte para string e extrai o primeiro dígito primeiro_digito <-str_sub(as.character(cfop), 1, 1)# Classifica com base no primeiro dígitocase_when( primeiro_digito ==1~"ENTRADAS DO ESTADO", primeiro_digito ==2~"ENTRADAS DE OUTROS ESTADOS", primeiro_digito ==3~"ENTRADAS DO EXTERIOR", primeiro_digito ==5~"SAÍDAS PARA O ESTADO", primeiro_digito ==6~"SAÍDAS PARA OUTROS ESTADOS", primeiro_digito ==7~"SAÍDAS DO EXTERIOR",TRUE~"OUTROS"# Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>%filter(!is.na(CODG_CFOP)) %>%# Remove linhas com CODG_CFOP NAmutate(CLASSIFICACAO_CFOP =classificar_cfop(CODG_CFOP))
2.Exportação 2023
Na etapa referente à exportação, o primeiro passo consiste em filtrar apenas os registros cuja origem seja o estado de Mato Grosso (MT) e o destino seja o exterior. Além disso, são selecionados apenas os CFOPs compatíveis com operações de exportação, garantindo a coerência dos dados analisados.
A escolha desses CFOPs se justifica pelo fato de suas descrições estarem diretamente relacionadas a operações de exportação. Durante o tratamento dos dados, foi identificado que nem toda operação cujo CFOP começa com o dígito 7, tradicionalmente associado à saída de mercadorias, é de fato uma exportação. Na realidade, entre os dados analisados, apenas um CFOP com esse prefixo correspondia a exportação, e seu valor representativo era irrisório. Diante disso, foi fundamental realizar uma análise detalhada das descrições e contextos de cada operação para assegurar a correta classificação.
CFOP
Grupo
Descrição
5501
5
Remessa de produção do estabelecimento, com fim específico de exportação
6501
6
Remessa de produção do estabelecimento, com fim específico de exportação
5502
5
Remessa de mercadoria adquirida ou recebida de terceiros, com fim específico de exportação
6502
6
Remessa de mercadoria adquirida ou recebida de terceiros, com fim específico de exportação
6504
6
Remessa de mercadoria para formação de lote de exportação, de produto industrializado ou produzido pelo próprio estabelecimento
5505
5
Remessa de mercadoria, adquirida ou recebida de terceiros, para formação de lote de exportação
6505
6
Remessa de mercadoria, adquirida ou recebida de terceiros, para formação de lote de exportação
2.2 Tratamento
Após a escolha dos CFOPs, foi necessário realizar a transformação das variáveis em toneladas, buscando incluir o maior número possível de descrições de unidades. Considerando que, frequentemente, a unidade descrita nos dados não corresponde exatamente ao que foi declarado, desenvolveu-se uma função para tentar “capturar a maioria dos casos relevantes”, assegurando uma melhor correspondência entre as unidades e seus respectivos registros.
Apesar de todas as unidades terem sido transformadas para toneladas, ainda assim persistem valores extremos. Para lidar com isso, foi realizada uma divisão dos valores com base no valor máximo registrado para cada modo de transporte: rodoviário, ferroviário e aéreo. Essa abordagem visa minimizar os efeitos de outliers e garantir uma análise mais precisa dos dados.
amostra2 %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus)) +geom_line() +labs(title ="Quantidade de Carga Ajustada ao Longo do Tempo",x ="Data de Emissão",y ="Quantidade de Carga (Toneladas)") +theme_minimal()
Observa-se que, após o tratamento, os dados não apresentam mais outliers significativos e seguem uma tendência semelhante à dos dados de exportação da Comex Stat. O volume final estimado é o seguinte (em milhões de toneladas):
28.34136 milhões de toneladas, o volume final estimado, e o valor reportado pela Comex Stat 28.33614
2.3 Comparação com a Comex Stat
Code
library(ggplot2)library(dplyr)library(lubridate)comex =import('Exportação_COMEX.xlsx')# 1. Converter e filtrar dados de amostra2 para 2023dados_carga <- amostra2 %>%mutate(DATA_EMISSAO_CTE =as.Date(DATA_EMISSAO_CTE), # Converter para DateAno =year(DATA_EMISSAO_CTE)) %>%filter(Ano ==2023) %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE))# 2. Converter e filtrar dados da Comex para 2023dados_comex <- comex %>%mutate(data =as.Date(data), # Converter para DateAno =year(data)) %>%filter(Ano ==2023)# 3. Criar o gráfico básico# Calcular fatores de escalafator_escala <-max(dados_comex$valor, na.rm =TRUE) /max(dados_carga$QTDE_CARGA_TON_ajus, na.rm =TRUE)ggplot() +geom_line(data = dados_carga, aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus, color ="Carga Ajustada"),linewidth =0.8) +geom_line(data = dados_comex, aes(x = data, y = valor/fator_escala, color ="Comex (Escala Ajustada)"),linewidth =0.8) +scale_y_continuous(name ="Carga Ajustada (Toneladas)",sec.axis =sec_axis(~.*fator_escala, name ="Valor Comex") ) +labs(title ="Comparação: Carga vs Comex (2023) - Eixos Escalonados",x ="Data",color ="Métrica") +scale_color_manual(values =c("Carga Ajustada"="#1f77b4", "Comex-Stat (Escala Ajustada)"="#ff7f0e")) +theme_minimal() +theme(legend.position ="bottom",plot.title =element_text(hjust =0.5, face ="bold"),axis.text.x =element_text(angle =45, hjust =1)) +scale_x_date(date_labels ="%b/%Y", date_breaks ="1 month")
Observa-se que os dados tratados seguem a mesma tendência das fontes de referência, o que indica que o processo de tratamento está alinhado com os valores esperados e validando, assim, a consistência da metodologia adotada.
3.Exportação 2024
Para o ano de 2024, foi aplicado exatamente o mesmo processo metodológico descrito anteriormente. Sendo assim, passamos agora à apresentação dos resultados obtidos após todo o tratamento dos dados.
Code
boxplot(amostra2$QTDE_CARGA_TON_ajus)
Code
amostra2 %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus)) +geom_line() +labs(title ="Quantidade de Carga Ajustada ao Longo do Tempo",x ="Data de Emissão",y ="Quantidade de Carga (Toneladas)") +theme_minimal()
Da mesma forma, os dados de exportação para 2024 seguem um comportamento muito semelhante ao observado em 2023, sem a presença de outliers relevantes. O volume final estimado para o ano é o seguinte (em milhões de toneladas):
O volume final estimado é de 23,33 milhões de toneladas, o que representa uma diferença de 1,41 milhão de toneladas a menos em relação ao valor divulgado pela Comex Stat para o mesmo ano(24,72722).
3.1 Comparação com a Comex-Stat
Code
library(ggplot2)library(dplyr)library(lubridate)comex =import('Exportação_COMEX.xlsx')# 1. Converter e filtrar dados de amostra2 para 2023dados_carga <- amostra2 %>%mutate(DATA_EMISSAO_CTE =as.Date(DATA_EMISSAO_CTE), # Converter para DateAno =year(DATA_EMISSAO_CTE)) %>%filter(Ano ==2024) %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE))# 2. Converter e filtrar dados da Comex para 2023dados_comex <- comex %>%mutate(data =as.Date(data), # Converter para DateAno =year(data)) %>%filter(Ano ==2024)# 3. Criar o gráfico básico# Calcular fatores de escalafator_escala <-max(dados_comex$valor, na.rm =TRUE) /max(dados_carga$QTDE_CARGA_TON_ajus, na.rm =TRUE)ggplot() +geom_line(data = dados_carga, aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus, color ="Carga Ajustada"),linewidth =0.8) +geom_line(data = dados_comex, aes(x = data, y = valor/fator_escala, color ="Comex (Escala Ajustada)"),linewidth =0.8) +scale_y_continuous(name ="Carga Ajustada (Toneladas)",sec.axis =sec_axis(~.*fator_escala, name ="Valor Comex") ) +labs(title ="Comparação: Carga vs Comex Stat (2024) - Eixos Escalonados",x ="Data",color ="Métrica") +scale_color_manual(values =c("Carga Ajustada"="#1f77b4", "Comex-Stats (Escala Ajustada)"="#ff7f0e")) +theme_minimal() +theme(legend.position ="bottom",plot.title =element_text(hjust =0.5, face ="bold"),axis.text.x =element_text(angle =45, hjust =1)) +scale_x_date(date_labels ="%b/%Y", date_breaks ="1 month")
4.Consumo Mato Grosso 2023
Para a estimativa de consumo em Mato Grosso, foi empregada a mesma metodologia de transformação de variáveis para toneladas. A única diferença em relação ao processo utilizado na exportação está na seleção dos CFOPs, que neste caso foram escolhidos com base em descrições compatíveis com operações de consumo interno.
4.1 Justificativa da escolha dos CFOP
Ao analisar os CFOPs iniciados pelo dígito 5, que correspondem a operações de consumo estadual, verificou-se que apenas dois deles possuem relevância significativa, sendo responsáveis por mais de 95% dos registros relacionados ao consumo interno. Diante disso, esses dois CFOPs foram selecionados para compor a base de análise.
CFOP
Grupo
Descrição
5101
5
Venda de produção do estabelecimento
5102
5
Venda de mercadoria adquirida ou recebida de terceiros
4.2 Tratamento e resultados
Após todo o processo de tratamento dos dados e remoção de outliers, obtiveram-se os seguintes resultados:
Podemos observar que, após o tratamento, o conjunto de dados não apresenta outliers relevantes. O volume final estimado de consumo interno é de 11,98 milhões de toneladas, valor muito próximo ao divulgado pelo site do IMEA, que foi de 11,76 milhões de toneladas — uma diferença de 0,21 milhão de toneladas a mais na estimativa.
5.Consumo Mato Grosso 2024
Para o ano de 2024, foi aplicado exatamente o mesmo processo metodológico, considerando os mesmos CFOPs selecionados para o consumo interno. Os resultados obtidos foram os seguintes:
Code
boxplot(amostra2$QTDE_CARGA_TON_ajus)
Code
library(lubridate)amostra2 %>%mutate(mes =floor_date(DATA_EMISSAO_CTE, "month")) %>%group_by(mes) %>%summarise(QTDE_CARGA_TON_ajus =mean(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = mes, y = QTDE_CARGA_TON_ajus)) +geom_line(color ="steelblue", size =1) +labs(title ="Média Mensal da Quantidade de Carga Ajustada",x ="Mês",y ="Quantidade Média de Carga (Toneladas)") +theme_minimal()
O valor final estimado foi de 12,37 milhões de toneladas, enquanto o valor divulgado pelo Imea foi de 12,68 milhões de toneladas. Assim, a estimativa apresenta uma diferença de 0,31 milhão de toneladas a menos em relação ao valor oficial.
6.Consumo Interestadual 2023
No que diz respeito ao consumo interestadual, a primeira etapa do tratamento seguiu o mesmo processo aplicado nas análises anteriores. No entanto, os CFOPs relacionados a esse tipo de operação são bem mais variados e distribuídos, o que torna o conjunto de dados mais heterogêneo. Ao realizar a transformação para toneladas, observou-se a presença de muitos outliers. No entanto, a simples remoção desses valores extremos não é recomendada, pois implicaria na perda de informações relevantes. Por isso, optou-se por realizar um tratamento específico para esses casos, visando preservar a integridade dos dados e garantir uma análise mais precisa.
6.1 Justificativa da escolha dos CFOP
A escolha desses CFOPs se justifica por refletirem diretamente as operações de consumo interestadual de soja, permitindo identificar com maior precisão as saídas de mercadoria destinadas a outros estados e, consequentemente, estimar o volume consumido fora de Mato Grosso.
CFOP
Grupo
Descrição
6101
6
Venda de produção do estabelecimento
6102
6
Venda de mercadoria adquirida ou recebida de terceiros
6105
6
Venda de produção do estabelecimento que não deva por ele transitar
6106
6
Venda de mercadoria adquirida ou recebida de terceiros, que não deva por ele transitar
6110
6
Venda de mercadoria adquirida ou recebida de terceiros, destinada à Zona Franca de Manaus ou áreas de livre comércio
6116
6
Venda de produção do estabelecimento originada de encomenda para entrega futura
6117
6
Venda de mercadoria adquirida ou recebida de terceiros, originada de encomenda para entrega futura
6118
6
Venda de produção do estabelecimento entregue ao destinatário por conta e ordem do adquirente originário, em venda à ordem
6119
6
Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário por conta e ordem do adquirente originário, em venda à ordem
6120
6
Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário pelo vendedor remetente, em venda à ordem
6122
6
Venda de produção do estabelecimento remetida para industrialização, por conta e ordem do adquirente, sem transitar pelo estabelecimento do adquirente
6151
6
Transferência de produção do estabelecimento
6152
6
Transferência de mercadoria adquirida ou recebida de terceiros
6155
6
Transferência de produção do estabelecimento, que não deva por ele transitar
6156
6
Transferência de mercadoria adquirida ou recebida de terceiros, que não deva por ele transitar
6557
6
Transferência de material de uso ou consumo
6906
6
Retorno de mercadoria depositada em depósito fechado ou armazém geral
Como podemos observar no gráfico, a maioria dos registros apresenta valores relativamente baixos, porém há uma quantidade significativa de dados com valores muito elevados. No entanto, não é adequado classificá-los automaticamente como outliers, pois podem representar operações legítimas de grande porte. Diante disso, foram consideradas três alternativas para lidar com essa situação, todas baseadas no uso do método do intervalo interquartil (IQR) como critério para tratamento dos dados extremos.
6.3 Metodo substituição interquartil
Esse método é conhecido como “substituição interquartil”, ou mais especificamente, “capamento por percentis”, utilizando neste caso os percentis de 1% (P1) e 99% (P99).
Em séries de dados de tonelagem, é comum surgirem valores extremamente altos — muitas vezes causados por erros de digitação ou registros anômalos — que acabam inflando artificialmente a soma total.
Ao aplicar o capamento por percentis:
Um valor atípico, como 1.000.000 toneladas, pode ser reduzido para algo mais plausível, como 20.000 toneladas, caso esse seja o valor do percentil 99.
Da mesma forma, valores extremamente baixos, como 0,0001, podem ser elevados até o valor correspondente ao percentil 1, por exemplo, 5 toneladas.
Esse tipo de ajuste preserva a estrutura geral dos dados, evitando distorções provocadas por valores extremos, sem simplesmente eliminar registros potencialmente válidos.
Code
p1 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# Supondo que amostra2 já tenha a coluna QTDE_CARGA_TONdf <- amostra2 %>%# 1) manter cópia íntegra antes de qualquer ajustemutate(QTDE_ORIGINAL = QTDE_CARGA_TON) %>%# 2) calcular os percentis de 1% e 99% { p1 <-quantile(.$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE) p99 <-quantile(.$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)bind_cols(., tibble(P1 = p1, P99 = p99)) } %>%# 3) cap nos percentis (entre P1 e P99)mutate(QTDE_CAP_PERCENTIL =pmin(pmax(QTDE_CARGA_TON, P1), P99),# 4) alternativa com pmin/pmax diretos (exemplo fixo)QTDE_CAP_FIXO =pmin(pmax(QTDE_CARGA_TON, 10), 10000) ) %>%# 5) opcional: remover colunas auxiliaresselect(-P1, -P99)
Code
# Exemplo com dados agrupados por tempo (ajuste conforme seus dados)df_grouped <- df %>%group_by(DATA_EMISSAO_CTE) %>%# Substitua pela sua coluna de temposummarise(total_pct =sum(QTDE_CAP_PERCENTIL, na.rm =TRUE))ggplot(df_grouped, aes(x = DATA_EMISSAO_CTE, y = total_pct /1e6)) +geom_line(color ="steelblue", size =1) +labs(title ="Total de Carga com Capping 1-99%",x ="Período",y ="Total (Mt)") +theme_minimal()
Code
total_pct <-sum(df$QTDE_CAP_PERCENTIL, na.rm =TRUE) # coluna a se considerarcat("Total cap 1–99% (Mt):", total_pct /1e6, "\n")
Total cap 1–99% (Mt): 5.262106
Após a aplicação desse tratamento, o valor estimado de consumo interestadual foi de 5,26 milhões de toneladas, enquanto o valor divulgado pelo site do IMEA é de 5,31 milhões de toneladas. Isso indica uma diferença de 0,05 milhão de toneladas entre a estimativa e o valor oficial.
Vale ressaltar que, ao limitar valores extremos ao percentils de 1% e 99%, o método pode distorcer e distribuição original de dados.
6.4 Método substituição pela mediana
No método de substituição pela mediana, o processo também começa com o cálculo dos percentis para identificar valores extremos. No entanto, ao invés de substituir os outliers pelos próprios valores dos percentis (como no capamento), eles são substituídos pela mediana dos dados, considerando o agrupamento por município de origem e destino. Essa abordagem permite suavizar os valores discrepantes mantendo as características específicas de cada rota, preservando padrões regionais importantes na análise.
Code
#Mediana - Metodo substituição interqualtillibrary(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(df$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(df$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular mediana por rota (origem + destino)medianas_rotas <- df %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIANA_ROTA =median(QTDE_CARGA_TON, na.rm =TRUE), .groups ="drop")# 3. Juntar a mediana por rota de volta no dataframe originaldfmed <- df %>%left_join(medianas_rotas, by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE"))# 4. Substituir valores extremos pela mediana da rotadfmed <- dfmed %>%mutate(QTDE_MEDIANA_POR_ROTA =ifelse(QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIANA_ROTA, QTDE_CARGA_TON))# 5. Verificar os somatóriostotal_original <-sum(dfmed$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(dfmed$QTDE_MEDIANA_POR_ROTA, na.rm =TRUE) # coluna de interesse
Code
library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- dfmed %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIANA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Mediana por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)
Fazendo a substuição pela mediana, pode perceber que os dados são menos dispersos e a o valor final é de :
Code
cat("Total com mediana por rota (Mt):", total_ajustado /1e6, "\n")
Total com mediana por rota (Mt): 4.505226
O resultado estimado foi de 4,51 milhões de toneladas, o que representa uma diferença de 0,80 milhão a menos em relação aos 5,31 milhões de toneladas divulgados pelo IMEA.
6.5 Método da Substuição pela média
No método de substituição pela mediana, o processo também começa com o cálculo dos percentis para identificar valores extremos. No entanto, ao invés de substituir os outliers pelos próprios valores dos percentis (como no capamento), eles são substituídos pela média dos dados, considerando o agrupamento por município de origem e destino.
Code
library(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular média por rota (origem + destino) a partir de dfmedmedias_rotas <- dfmed %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIA_ROTA =mean(QTDE_CARGA_TON, na.rm =TRUE),.groups ="drop" )# 3. Montar defmedia a partir de dfmed, juntando a média por rotadefmedia <- df %>%left_join( medias_rotas,by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE") ) %>%# 4. Criar coluna com substituição de extremos pela média da rotamutate(QTDE_MEDIA_POR_ROTA =ifelse( QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIA_ROTA, QTDE_CARGA_TON ) )# 5. Verificar os somatóriostotal_original <-sum(defmedia$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(defmedia$QTDE_MEDIA_POR_ROTA, na.rm =TRUE) # coluna de interesse
Code
library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- defmedia %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Média por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)
Ao aplicar a substituição pela média, observamos um comportamento semelhante ao obtido com a mediana. No entanto, como a média é sensível a valores extremos, o resultado final tende a ser um pouco mais elevado.
Code
cat("Total com média por rota (Mt): ", total_ajustado /1e6, "\n")
Total com média por rota (Mt): 5.781895
O resultado estimado foi de 5,78 milhões de toneladas, valor superior aos 5,31 milhões divulgados pelo IMEA, o que representa uma diferença de 0,47 milhão de toneladas.
7.Consumo Interestadual 2024
Para o ano de 2024, foi realizado exatamente o mesmo tratamento. Sendo assim, apresentamos a seguir apenas os resultados obtidos.
7.1 Método substituição interquartil
Code
# Calcular os percentisp1 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)#Metodo substituição interqualtil# Supondo que amostra2 já tenha a coluna QTDE_CARGA_TONdf <- amostra2 %>%# 1) manter cópia íntegra antes de qualquer ajustemutate(QTDE_ORIGINAL = QTDE_CARGA_TON) %>%# 2) calcular os percentis de 1% e 99% { p1 <-quantile(.$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE) p99 <-quantile(.$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)bind_cols(., tibble(P1 = p1, P99 = p99)) } %>%# 3) cap nos percentis (entre P1 e P99)mutate(QTDE_CAP_PERCENTIL =pmin(pmax(QTDE_CARGA_TON, P1), P99),# 4) alternativa com pmin/pmax diretos (exemplo fixo)QTDE_CAP_FIXO =pmin(pmax(QTDE_CARGA_TON, 10), 10000) ) %>%# 5) opcional: remover colunas auxiliaresselect(-P1, -P99)# Agora você tem:# - QTDE_ORIGINAL : valores sem cap (para somatório total)# - QTDE_CAP_PERCENTIL : valores capados entre 1º e 99º percentil# - QTDE_CAP_FIXO : exemplo de cap fixo entre 10 e 1000# Somatórios para comparaçãototal_orig <-sum(df$QTDE_ORIGINAL, na.rm =TRUE)total_pct <-sum(df$QTDE_CAP_PERCENTIL, na.rm =TRUE) # coluna a se considerartotal_fixo <-sum(df$QTDE_CAP_FIXO, na.rm =TRUE)
Code
# Exemplo com dados agrupados por tempo (ajuste conforme seus dados)df_grouped <- df %>%group_by(DATA_EMISSAO_CTE) %>%# Substitua pela sua coluna de temposummarise(total_pct =sum(QTDE_CAP_PERCENTIL, na.rm =TRUE))ggplot(df_grouped, aes(x = DATA_EMISSAO_CTE, y = total_pct /1e6)) +geom_line(color ="steelblue", size =1) +labs(title ="Total de Carga com Capping 1-99%",x ="Período",y ="Total (Mt)") +theme_minimal()
Aplicando o método substuição interquartil, observamos o seguinte comportamento na série de dados, resultando em um valor estimado de consumo interestadual de:
Code
sum(df$QTDE_CAP_PERCENTIL)/1000000
[1] 8.61355
8.61 milhões para 2024 , valor consideravelmente acima dos 2,10 milhões divulgados pelo Imea.
7.2 Método substituição pela mediana
Code
#Mediana - Metodo substituição interqualtillibrary(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(df$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(df$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular mediana por rota (origem + destino)medianas_rotas <- df %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIANA_ROTA =median(QTDE_CARGA_TON, na.rm =TRUE), .groups ="drop")# 3. Juntar a mediana por rota de volta no dataframe originaldfmed <- df %>%left_join(medianas_rotas, by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE"))# 4. Substituir valores extremos pela mediana da rotadfmed <- dfmed %>%mutate(QTDE_MEDIANA_POR_ROTA =ifelse(QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIANA_ROTA, QTDE_CARGA_TON))# 5. Verificar os somatóriostotal_original <-sum(dfmed$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(dfmed$QTDE_MEDIANA_POR_ROTA, na.rm =TRUE) # coluna de interesse
Code
library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- dfmed %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIANA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Mediana por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)
No método da mediana novamente temos os dados mais estabilizados, e o valor de :
Code
cat("Total com mediana por rota (Mt):", total_ajustado /1e6, "\n")
Total com mediana por rota (Mt): 2.857583
2.86 Milhões de tonelas, próximo ao valor de 2.10 divulgados pelo imea.
7.3 Método substituição pela média
Code
library(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular média por rota (origem + destino) a partir de dfmedmedias_rotas <- dfmed %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIA_ROTA =mean(QTDE_CARGA_TON, na.rm =TRUE),.groups ="drop" )# 3. Montar defmedia a partir de dfmed, juntando a média por rotadefmedia <- df %>%left_join( medias_rotas,by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE") ) %>%# 4. Criar coluna com substituição de extremos pela média da rotamutate(QTDE_MEDIA_POR_ROTA =ifelse( QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIA_ROTA, QTDE_CARGA_TON ) )# 5. Verificar os somatóriostotal_original <-sum(defmedia$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(defmedia$QTDE_MEDIA_POR_ROTA, na.rm =TRUE) # coluna de interesse
Code
library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- defmedia %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Média por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)
Novamente, fazendo a substuição pela média, temos uma dispersão maior e o valor final de:
Code
cat("Total com média por rota (Mt): ", total_ajustado /1e6, "\n")
Total com média por rota (Mt): 4.346559
8.Conclusões
Podemos concluir que a metodologia adotada tem se mostrado eficaz, especialmente para os dados de exportação e de consumo dentro do estado de Mato Grosso. No entanto, no que diz respeito ao consumo interestadual, a diversidade de CFOPs com características distintas exige uma avaliação mais criteriosa entre os três métodos apresentados, a fim de garantir maior precisão na estimativa final.
2023
2024
Categoria
Estimado 2023
Real 2023
Diferença 2023
Estimado 2024
Real 2024
Diferença 2024
Exportação
28.34
28.34
0.00
23.33
24.73
-1.40
Consumo MT
11.98
11.76
0.22
12.37
12.68
-0.31
Consumo INER(Interquartil)
5.26
5.31
-0.05
8.61
2.10
6.51
Consumo INER (Mediana)
4.51
5.31
-0.80
2.86
2.10
0.76
Consumo INER (Média)
5.78
5.31
0.47
4.35
2.10
2.25
Note:
Valores em milhões de unidades
Source Code
---title: "Metodologia dados SEFAZ"author: ""date: ""format: html: code-fold: true code-tools: true theme: journal toc: true # Habilita o sumário toc-depth: 3 # Níveis de cabeçalho a incluir (1 a 6) toc-location: left # Opcional: posição (left/right) toc-title: "Sumário" # Opcional: título personalizado---Este documento apresenta, de forma clara e estruturada, a metodologia aplicada ao tratamento dos dados de exportação, consumo interno (Mato Grosso) e consumo interestadual da cadeia da soja. A análise utiliza os dados disponibilizados pela SEFAZ referentes aos anos de 2023 e 2024. A seguir, é descrito passo a passo o processo de tratamento, destacando os CFOPs utilizados e as técnicas estatísticas empregadas.# 1.Processo padrão para todos os casosNo primeiro passo, os dados são importados separadamente por ano e por NCM. Em seguida, são realizadas as transformações necessárias, como a conversão de colunas originalmente em formato de texto que representam valores numéricos e a remoção de valores duplicados, o ajuste de colunas de datas para o formato adequado e a junção das bases com as informações de NCM. Na sequência, é feita a classificação dos CFOPs com base no primeiro dígito, permitindo identificar a natureza de cada operação.```{r, warning=FALSE, message=FALSE}rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio, stringdist, scales)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2024 , NCM e juntar as basesdados_2024 = read_parquet('IMEA_2023_novo.parquet')NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)amostra = dados #remover valores duplicadosamostra <- amostra %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_PRODUTO)))# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_UNIDADE_COMERCIAL)))# quantidade de cargaamostra$QTDE_CARGA <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$QTDE_CARGA)))# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO<- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALOR_PRESTACAO_SERVICO)))classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS DO EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))```# 2.Exportação 2023Na etapa referente à exportação, o primeiro passo consiste em filtrar apenas os registros cuja origem seja o estado de Mato Grosso (MT) e o destino seja o exterior. Além disso, são selecionados apenas os CFOPs compatíveis com operações de exportação, garantindo a coerência dos dados analisados.```{r}amostra1 = amostra %>%filter(Produto =='Soja'& UF_ORIGEM_CTE =='MT')amostra = amostra1 %>%filter (!UF_DESTINO_CTE =="MT")# CFOP que indica amostra <- amostra %>%filter(CODG_CFOP %in%c(6505,6502,6504,5502,6501,5505,5501))```## 2.1 Justificativa da escolha dos CFOPA escolha desses CFOPs se justifica pelo fato de suas descrições estarem diretamente relacionadas a operações de exportação. Durante o tratamento dos dados, foi identificado que nem toda operação cujo CFOP começa com o dígito 7, tradicionalmente associado à saída de mercadorias, é de fato uma exportação. Na realidade, entre os dados analisados, apenas um CFOP com esse prefixo correspondia a exportação, e seu valor representativo era irrisório. Diante disso, foi fundamental realizar uma análise detalhada das descrições e contextos de cada operação para assegurar a correta classificação.```{r, warning=FALSE, message=FALSE, echo=FALSE}library(knitr)library(kableExtra)dados <- data.frame( CFOP = c(5501, 6501, 5502, 6502, 6504, 5505, 6505), Grupo = c(5, 6, 5, 6, 6, 5, 6), Descrição = c( "Remessa de produção do estabelecimento, com fim específico de exportação", "Remessa de produção do estabelecimento, com fim específico de exportação", "Remessa de mercadoria adquirida ou recebida de terceiros, com fim específico de exportação", "Remessa de mercadoria adquirida ou recebida de terceiros, com fim específico de exportação", "Remessa de mercadoria para formação de lote de exportação, de produto industrializado ou produzido pelo próprio estabelecimento", "Remessa de mercadoria, adquirida ou recebida de terceiros, para formação de lote de exportação", "Remessa de mercadoria, adquirida ou recebida de terceiros, para formação de lote de exportação" ))kable(dados, "html", escape = FALSE, col.names = c("CFOP", "Grupo", "Descrição")) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, position = "center") %>% column_spec(1, bold = TRUE) %>% column_spec(2, bold = TRUE, color = "white", background = "#f58723") %>% column_spec(3, width = "50em")```## 2.2 TratamentoApós a escolha dos CFOPs, foi necessário realizar a transformação das variáveis em toneladas, buscando incluir o maior número possível de descrições de unidades. Considerando que, frequentemente, a unidade descrita nos dados não corresponde exatamente ao que foi declarado, desenvolveu-se uma função para tentar "capturar a maioria dos casos relevantes", assegurando uma melhor correspondência entre as unidades e seus respectivos registros.```{r}# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <-function(amostra) { amostra <- amostra %>%mutate(QTDE_CARGA_TON =case_when(# Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, # 1 KG = 0.001 TON UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("_", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("UN", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="KG"&str_detect(TIPO_MEDIDA, regex("TONELADA", ignore_case =TRUE)) ~ QTDE_CARGA *1, # 1 QUILO = 0.001 TON# Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA =="TON"~ QTDE_CARGA*0.001, # Já está em toneladas# Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case =TRUE)) ~ QTDE_CARGA *1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case =TRUE)) ~ QTDE_CARGA *1, UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case =TRUE)) ~ QTDE_CARGA *1, UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1), UNIDADE_MEDIDA =="UNIDADE"&str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1),# Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA =="M3"&str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case =TRUE)) ~ QTDE_CARGA *0.001, # 1 M3 = 0.72 TON UNIDADE_MEDIDA =="M3"&str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1),# casos de unidades UNIDADE_MEDIDA =="LITROS"&str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO", ignore_case =TRUE)) ~ifelse(QTDE_CARGA >1000, QTDE_CARGA *0.001, QTDE_CARGA *1),# Casos não mapeados ou sem peso específicoTRUE~NA_real_# Retorna NA para casos não tratados ))return(amostra)}# Aplicar a função de conversãoamostra2 <-converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>%filter(is.na(QTDE_CARGA_TON))amostra2 %>%filter(!is.na(QTDE_CARGA_TON)) %>%ggplot(aes(x = QTDE_CARGA_TON)) +geom_boxplot() +labs(title ="Boxplot da Quantidade de Carga (Toneladas)",x ="Quantidade de Carga (Toneladas)") +theme_minimal()```Apesar de todas as unidades terem sido transformadas para toneladas, ainda assim persistem valores extremos. Para lidar com isso, foi realizada uma divisão dos valores com base no valor máximo registrado para cada modo de transporte: rodoviário, ferroviário e aéreo. Essa abordagem visa minimizar os efeitos de outliers e garantir uma análise mais precisa dos dados.```{r}amostra2 <- amostra2 %>%mutate(QTDE_CARGA_TON_ajus =case_when( MODO_TRANSPORTE =="RODOVIARIO"& QTDE_CARGA_TON >70~ QTDE_CARGA_TON /1000, MODO_TRANSPORTE =="AEREO"& QTDE_CARGA_TON >70~ QTDE_CARGA_TON /1000, MODO_TRANSPORTE =="FERROVIARIO"& QTDE_CARGA_TON >15600~ QTDE_CARGA_TON /1000,TRUE~ QTDE_CARGA_TON ))```Depois de feita mais uma conversão , é feita duas remoção de outilers para minimizar as variações bruscas, utilizando o médoto interquartil.```{r}amostra2 <- amostra2 %>%filter(!QTDE_CARGA_TON_ajus %in%boxplot.stats(QTDE_CARGA_TON_ajus)$out)#----------------------------------------------------------------------------#amostra2 <- amostra2 %>%filter(!QTDE_CARGA_TON_ajus %in%boxplot.stats(QTDE_CARGA_TON_ajus)$out)#-----------------------------------------------------------------------------#boxplot(amostra2$QTDE_CARGA_TON_ajus)amostra2 %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus)) +geom_line() +labs(title ="Quantidade de Carga Ajustada ao Longo do Tempo",x ="Data de Emissão",y ="Quantidade de Carga (Toneladas)") +theme_minimal()```Observa-se que, após o tratamento, os dados não apresentam mais outliers significativos e seguem uma tendência semelhante à dos dados de exportação da Comex Stat. O volume final estimado é o seguinte (em milhões de toneladas):```{r}sum(amostra2$QTDE_CARGA_TON_ajus, na.rm =TRUE)/1000000```**28.34136** milhões de toneladas, o volume final estimado, e o valor reportado pela Comex Stat 28.33614## 2.3 Comparação com a Comex Stat```{r,warning=FALSE,message=FALSE}library(ggplot2)library(dplyr)library(lubridate)comex = import('Exportação_COMEX.xlsx')# 1. Converter e filtrar dados de amostra2 para 2023dados_carga <- amostra2 %>% mutate(DATA_EMISSAO_CTE = as.Date(DATA_EMISSAO_CTE), # Converter para Date Ano = year(DATA_EMISSAO_CTE)) %>% filter(Ano == 2023) %>% group_by(DATA_EMISSAO_CTE) %>% summarise(QTDE_CARGA_TON_ajus = sum(QTDE_CARGA_TON_ajus, na.rm = TRUE))# 2. Converter e filtrar dados da Comex para 2023dados_comex <- comex %>% mutate(data = as.Date(data), # Converter para Date Ano = year(data)) %>% filter(Ano == 2023)# 3. Criar o gráfico básico# Calcular fatores de escalafator_escala <- max(dados_comex$valor, na.rm = TRUE) / max(dados_carga$QTDE_CARGA_TON_ajus, na.rm = TRUE)ggplot() + geom_line(data = dados_carga, aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus, color = "Carga Ajustada"), linewidth = 0.8) + geom_line(data = dados_comex, aes(x = data, y = valor/fator_escala, color = "Comex (Escala Ajustada)"), linewidth = 0.8) + scale_y_continuous( name = "Carga Ajustada (Toneladas)", sec.axis = sec_axis(~.*fator_escala, name = "Valor Comex") ) + labs(title = "Comparação: Carga vs Comex (2023) - Eixos Escalonados", x = "Data", color = "Métrica") + scale_color_manual(values = c("Carga Ajustada" = "#1f77b4", "Comex-Stat (Escala Ajustada)" = "#ff7f0e")) + theme_minimal() + theme(legend.position = "bottom", plot.title = element_text(hjust = 0.5, face = "bold"), axis.text.x = element_text(angle = 45, hjust = 1)) + scale_x_date(date_labels = "%b/%Y", date_breaks = "1 month")```Observa-se que os dados tratados seguem a mesma tendência das fontes de referência, o que indica que o processo de tratamento está alinhado com os valores esperados e validando, assim, a consistência da metodologia adotada.# 3.Exportação 2024Para o ano de 2024, foi aplicado exatamente o mesmo processo metodológico descrito anteriormente. Sendo assim, passamos agora à apresentação dos resultados obtidos após todo o tratamento dos dados.```{r, warning=FALSE,message=FALSE, echo = FALSE}# exportação 2024rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio, stringdist, scales)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2024 , NCM e juntar as basesdados_2024 = read_parquet('IMEA_2024_novo.parquet')NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)# Filtrar soja e origem MTamostra1 = dados %>% filter(Produto == 'Soja' & UF_ORIGEM_CTE == 'MT')amostra = amostra1 %>% filter (!UF_DESTINO_CTE == "MT")#remover valores duplicadosamostra <- amostra %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_PRODUTO)))# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_UNIDADE_COMERCIAL)))# quantidade de cargaamostra$QTDE_CARGA <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$QTDE_CARGA)))# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO<- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALOR_PRESTACAO_SERVICO)))classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS DO EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))#c(# 7501, 5501, 6501, 5502,# 6502, 5504, 6504, 5505,# 6505, 3503, 5503, 6503,# 1503, 2503, 1504, 2504#)# CFOP que indica amostra <- amostra %>% filter(CODG_CFOP %in% c( 6505,6502,6504, 5502,6501,5505, 5501))df = amostra#----------------------------------#amostra = df# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <- function(amostra) { amostra <- amostra %>% mutate(QTDE_CARGA_TON = case_when( # Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 KG = 0.001 TON UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("_", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("UN", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("TONELADA", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON # Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA == "TON" ~ QTDE_CARGA*0.001, # Já está em toneladas # Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case = TRUE)) ~ QTDE_CARGA * 1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case = TRUE)) ~ QTDE_CARGA *1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 M3 = 0.72 TON UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # casos de unidades UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Casos não mapeados ou sem peso específico TRUE ~ NA_real_ # Retorna NA para casos não tratados )) return(amostra)}# Aplicar a função de conversãoamostra2 <- converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>% filter(is.na(QTDE_CARGA_TON))#----------------------------------------------------------------------------#amostra2 <- amostra2 %>% mutate(QTDE_CARGA_TON_ajus = case_when( MODO_TRANSPORTE == "RODOVIARIO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "AEREO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "FERROVIARIO" & QTDE_CARGA_TON > 15600 ~ QTDE_CARGA_TON / 1000, TRUE ~ QTDE_CARGA_TON ))amostra2 <- amostra2 %>% filter(!QTDE_CARGA_TON_ajus %in% boxplot.stats(QTDE_CARGA_TON_ajus)$out)amostra2 <- amostra2 %>% filter(!QTDE_CARGA_TON_ajus %in% boxplot.stats(QTDE_CARGA_TON_ajus)$out)``````{r}boxplot(amostra2$QTDE_CARGA_TON_ajus)amostra2 %>%group_by(DATA_EMISSAO_CTE) %>%summarise(QTDE_CARGA_TON_ajus =sum(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus)) +geom_line() +labs(title ="Quantidade de Carga Ajustada ao Longo do Tempo",x ="Data de Emissão",y ="Quantidade de Carga (Toneladas)") +theme_minimal()```Da mesma forma, os dados de exportação para 2024 seguem um comportamento muito semelhante ao observado em 2023, sem a presença de outliers relevantes. O volume final estimado para o ano é o seguinte (em milhões de toneladas):```{r}sum(amostra2$QTDE_CARGA_TON_ajus, na.rm =TRUE)/1000000```O volume final estimado é de **23,33 milhões de toneladas**, o que representa uma diferença de 1,41 milhão de toneladas a menos em relação ao valor divulgado pela Comex Stat para o mesmo ano(24,72722).## 3.1 Comparação com a Comex-Stat```{r,warning=FALSE,message=FALSE}library(ggplot2)library(dplyr)library(lubridate)comex = import('Exportação_COMEX.xlsx')# 1. Converter e filtrar dados de amostra2 para 2023dados_carga <- amostra2 %>% mutate(DATA_EMISSAO_CTE = as.Date(DATA_EMISSAO_CTE), # Converter para Date Ano = year(DATA_EMISSAO_CTE)) %>% filter(Ano == 2024) %>% group_by(DATA_EMISSAO_CTE) %>% summarise(QTDE_CARGA_TON_ajus = sum(QTDE_CARGA_TON_ajus, na.rm = TRUE))# 2. Converter e filtrar dados da Comex para 2023dados_comex <- comex %>% mutate(data = as.Date(data), # Converter para Date Ano = year(data)) %>% filter(Ano == 2024)# 3. Criar o gráfico básico# Calcular fatores de escalafator_escala <- max(dados_comex$valor, na.rm = TRUE) / max(dados_carga$QTDE_CARGA_TON_ajus, na.rm = TRUE)ggplot() + geom_line(data = dados_carga, aes(x = DATA_EMISSAO_CTE, y = QTDE_CARGA_TON_ajus, color = "Carga Ajustada"), linewidth = 0.8) + geom_line(data = dados_comex, aes(x = data, y = valor/fator_escala, color = "Comex (Escala Ajustada)"), linewidth = 0.8) + scale_y_continuous( name = "Carga Ajustada (Toneladas)", sec.axis = sec_axis(~.*fator_escala, name = "Valor Comex") ) + labs(title = "Comparação: Carga vs Comex Stat (2024) - Eixos Escalonados", x = "Data", color = "Métrica") + scale_color_manual(values = c("Carga Ajustada" = "#1f77b4", "Comex-Stats (Escala Ajustada)" = "#ff7f0e")) + theme_minimal() + theme(legend.position = "bottom", plot.title = element_text(hjust = 0.5, face = "bold"), axis.text.x = element_text(angle = 45, hjust = 1)) + scale_x_date(date_labels = "%b/%Y", date_breaks = "1 month")```# 4.Consumo Mato Grosso 2023Para a estimativa de consumo em Mato Grosso, foi empregada a mesma metodologia de transformação de variáveis para toneladas. A única diferença em relação ao processo utilizado na exportação está na seleção dos CFOPs, que neste caso foram escolhidos com base em descrições compatíveis com operações de consumo interno.## 4.1 Justificativa da escolha dos CFOPAo analisar os CFOPs iniciados pelo dígito 5, que correspondem a operações de consumo estadual, verificou-se que apenas dois deles possuem relevância significativa, sendo responsáveis por mais de 95% dos registros relacionados ao consumo interno. Diante disso, esses dois CFOPs foram selecionados para compor a base de análise.```{r, warning=FALSE, message=FALSE, echo=FALSE}library(knitr)library(kableExtra)dados_venda <- data.frame( CFOP = c(5101, 5102), Grupo = c(5, 5), Descrição = c( "Venda de produção do estabelecimento", "Venda de mercadoria adquirida ou recebida de terceiros" ))kable(dados_venda, "html", escape = FALSE, col.names = c("CFOP", "Grupo", "Descrição")) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, position = "center") %>% column_spec(1, bold = TRUE) %>% column_spec(2, bold = TRUE, color = "white", background = "#f58723") %>% column_spec(3, width = "40em")```## 4.2 Tratamento e resultadosApós todo o processo de tratamento dos dados e remoção de outliers, obtiveram-se os seguintes resultados:```{r,warning=FALSE, message=FALSE,echo=FALSE}# Consumo estadual 2034rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio, stringdist, scales, lubridadte)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2024 , NCM e juntar as basesdados_2024 = read_parquet('IMEA_2023_novo.parquet')NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)# Filtrar soja e origem MTamostra1 = dados %>% filter(Produto == 'Soja' & UF_ORIGEM_CTE == 'MT')amostra = amostra1 %>% filter (UF_DESTINO_CTE == "MT")#remover valores duplicadosamostra <- amostra1 %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_PRODUTO)))# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_UNIDADE_COMERCIAL)))# quantidade de cargaamostra$QTDE_CARGA <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$QTDE_CARGA)))# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO<- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALOR_PRESTACAO_SERVICO)))classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS PARA O EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))# Filtrar apenas CFOPs relevantesdf = amostraamostra = df#------------------------------------------------#amostra <- amostra %>% filter(CODG_CFOP %in% c( 5101,5102 ))# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <- function(amostra) { amostra <- amostra %>% mutate(QTDE_CARGA_TON = case_when( # Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 KG = 0.001 TON UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("UN", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("Soja|LITRAGEM|30000|46000|37000|VOLUME|LIQUIDO|SOLIDA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("_|,|GANEL|PB|SEMENTE|BIG BAG|DIVERSAS|BAG|15000|36000|QUIULOGRAMA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("TONELADA|TON", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON # Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA == "TON" ~ QTDE_CARGA*0.001, # Já está em toneladas # Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case = TRUE)) ~ QTDE_CARGA * 1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.06, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case = TRUE)) ~ QTDE_CARGA *1, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 M3 = 0.72 TON UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg|PESO AFERIDO|PESO DECLARADO|PESO BASE DE CALCULO|QUILOGRAMAS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("KILOGRAMAS|CAIXAS|VOLUME|LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO CUBADO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # casos de unidades UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO|GRANEL", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("LITRAGEM|PESO LIQUIDO|GALAO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Casos não mapeados ou sem peso específico TRUE ~ NA_real_ # Retorna NA para casos não tratados )) return(amostra)}# Aplicar a função de conversãoamostra2 <- converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>% filter(is.na(QTDE_CARGA_TON))#----------------------------------------------------------------------------#amostra2 <- amostra2 %>% mutate(QTDE_CARGA_TON_ajus = case_when( MODO_TRANSPORTE == "RODOVIARIO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "AEREO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "FERROVIARIO" & QTDE_CARGA_TON > 15600 ~ QTDE_CARGA_TON / 1000, TRUE ~ QTDE_CARGA_TON ))amostra2 <- amostra2 %>% filter(!QTDE_CARGA_TON_ajus %in% boxplot.stats(QTDE_CARGA_TON_ajus)$out)``````{r,warning=FALSE,message=FALSE}library(lubridate)boxplot(amostra2$QTDE_CARGA_TON_ajus)amostra2 %>% mutate(mes = floor_date(DATA_EMISSAO_CTE, "month")) %>% group_by(mes) %>% summarise(QTDE_CARGA_TON_ajus = mean(QTDE_CARGA_TON_ajus, na.rm = TRUE)) %>% ggplot(aes(x = mes, y = QTDE_CARGA_TON_ajus)) + geom_line(color = "steelblue", size = 1) + labs(title = "Média Mensal da Quantidade de Carga Ajustada", x = "Mês", y = "Quantidade Média de Carga (Toneladas)") + theme_minimal()``````{r}sum(amostra2$QTDE_CARGA_TON_ajus, na.rm =TRUE)/1000000```Podemos observar que, após o tratamento, o conjunto de dados não apresenta outliers relevantes. O volume final estimado de consumo interno é de 11,98 milhões de toneladas, valor muito próximo ao divulgado pelo site do IMEA, que foi de 11,76 milhões de toneladas — uma diferença de 0,21 milhão de toneladas a mais na estimativa.# 5.Consumo Mato Grosso 2024Para o ano de 2024, foi aplicado exatamente o mesmo processo metodológico, considerando os mesmos CFOPs selecionados para o consumo interno. Os resultados obtidos foram os seguintes:```{r,warning=FALSE,message=FALSE,echo=FALSE}# Consumo estadual 2034rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio, stringdist, scales, lubridadte)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2024 , NCM e juntar as basesdados_2024 = read_parquet('IMEA_2024_novo.parquet')NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)# Filtrar soja e origem MTamostra1 = dados %>% filter(Produto == 'Soja' & UF_ORIGEM_CTE == 'MT')amostra = amostra1 %>% filter (UF_DESTINO_CTE == "MT")#remover valores duplicadosamostra <- amostra1 %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_PRODUTO)))# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALR_UNIDADE_COMERCIAL)))# quantidade de cargaamostra$QTDE_CARGA <- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$QTDE_CARGA)))# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO<- as.numeric(gsub(",", ".", gsub("\\.", "", amostra$VALOR_PRESTACAO_SERVICO)))classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS PARA O EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))# Filtrar apenas CFOPs relevantesdf = amostraamostra = df#------------------------------------------------#amostra <- amostra %>% filter(CODG_CFOP %in% c( 5101,5102 ))# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <- function(amostra) { amostra <- amostra %>% mutate(QTDE_CARGA_TON = case_when( # Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 KG = 0.001 TON UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("UN", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("Soja|LITRAGEM|30000|46000|37000|VOLUME|LIQUIDO|SOLIDA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), #UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("_|,|GANEL|PB|SEMENTE|BIG BAG|DIVERSAS|BAG|15000|36000|QUIULOGRAMA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("TONELADA|TON", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON # Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA == "TON" ~ QTDE_CARGA*0.001, # Já está em toneladas # Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case = TRUE)) ~ QTDE_CARGA * 1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.06, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case = TRUE)) ~ QTDE_CARGA *1, #UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 M3 = 0.72 TON UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg|PESO AFERIDO|PESO DECLARADO|PESO BASE DE CALCULO|QUILOGRAMAS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("KILOGRAMAS|CAIXAS|VOLUME|LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO CUBADO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # casos de unidades UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO|GRANEL", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("LITRAGEM|PESO LIQUIDO|GALAO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Casos não mapeados ou sem peso específico TRUE ~ NA_real_ # Retorna NA para casos não tratados )) return(amostra)}# Aplicar a função de conversãoamostra2 <- converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>% filter(is.na(QTDE_CARGA_TON))#----------------------------------------------------------------------------#amostra2 <- amostra2 %>% mutate(QTDE_CARGA_TON_ajus = case_when( MODO_TRANSPORTE == "RODOVIARIO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "AEREO" & QTDE_CARGA_TON > 70 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "FERROVIARIO" & QTDE_CARGA_TON > 15600 ~ QTDE_CARGA_TON / 1000, TRUE ~ QTDE_CARGA_TON ))amostra2 <- amostra2 %>% filter(!QTDE_CARGA_TON_ajus %in% boxplot.stats(QTDE_CARGA_TON_ajus)$out)amostra2 <- amostra2 %>% filter(!QTDE_CARGA_TON_ajus %in% boxplot.stats(QTDE_CARGA_TON_ajus)$out)``````{r}boxplot(amostra2$QTDE_CARGA_TON_ajus)library(lubridate)amostra2 %>%mutate(mes =floor_date(DATA_EMISSAO_CTE, "month")) %>%group_by(mes) %>%summarise(QTDE_CARGA_TON_ajus =mean(QTDE_CARGA_TON_ajus, na.rm =TRUE)) %>%ggplot(aes(x = mes, y = QTDE_CARGA_TON_ajus)) +geom_line(color ="steelblue", size =1) +labs(title ="Média Mensal da Quantidade de Carga Ajustada",x ="Mês",y ="Quantidade Média de Carga (Toneladas)") +theme_minimal()``````{r}sum(amostra2$QTDE_CARGA_TON_ajus, na.rm =TRUE)/1000000```O valor final estimado foi de 12,37 milhões de toneladas, enquanto o valor divulgado pelo Imea foi de 12,68 milhões de toneladas. Assim, a estimativa apresenta uma diferença de 0,31 milhão de toneladas a menos em relação ao valor oficial.# 6.Consumo Interestadual 2023No que diz respeito ao consumo interestadual, a primeira etapa do tratamento seguiu o mesmo processo aplicado nas análises anteriores. No entanto, os CFOPs relacionados a esse tipo de operação são bem mais variados e distribuídos, o que torna o conjunto de dados mais heterogêneo. Ao realizar a transformação para toneladas, observou-se a presença de muitos outliers. No entanto, a simples remoção desses valores extremos não é recomendada, pois implicaria na perda de informações relevantes. Por isso, optou-se por realizar um tratamento específico para esses casos, visando preservar a integridade dos dados e garantir uma análise mais precisa.## 6.1 Justificativa da escolha dos CFOPA escolha desses CFOPs se justifica por refletirem diretamente as operações de consumo interestadual de soja, permitindo identificar com maior precisão as saídas de mercadoria destinadas a outros estados e, consequentemente, estimar o volume consumido fora de Mato Grosso.```{r, warning=FALSE, message=FALSE, echo=FALSE}library(knitr)library(kableExtra)dados_venda_grupo6 <- data.frame( CFOP = c(6101, 6102, 6105, 6106, 6110, 6116, 6117, 6118, 6119, 6120, 6122, 6151, 6152, 6155, 6156, 6557, 6906), Grupo = rep(6, 17), Descrição = c( "Venda de produção do estabelecimento", "Venda de mercadoria adquirida ou recebida de terceiros", "Venda de produção do estabelecimento que não deva por ele transitar", "Venda de mercadoria adquirida ou recebida de terceiros, que não deva por ele transitar", "Venda de mercadoria adquirida ou recebida de terceiros, destinada à Zona Franca de Manaus ou áreas de livre comércio", "Venda de produção do estabelecimento originada de encomenda para entrega futura", "Venda de mercadoria adquirida ou recebida de terceiros, originada de encomenda para entrega futura", "Venda de produção do estabelecimento entregue ao destinatário por conta e ordem do adquirente originário, em venda à ordem", "Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário por conta e ordem do adquirente originário, em venda à ordem", "Venda de mercadoria adquirida ou recebida de terceiros entregue ao destinatário pelo vendedor remetente, em venda à ordem", "Venda de produção do estabelecimento remetida para industrialização, por conta e ordem do adquirente, sem transitar pelo estabelecimento do adquirente", "Transferência de produção do estabelecimento", "Transferência de mercadoria adquirida ou recebida de terceiros", "Transferência de produção do estabelecimento, que não deva por ele transitar", "Transferência de mercadoria adquirida ou recebida de terceiros, que não deva por ele transitar", "Transferência de material de uso ou consumo", "Retorno de mercadoria depositada em depósito fechado ou armazém geral" ))kable(dados_venda_grupo6, "html", escape = FALSE, col.names = c("CFOP", "Grupo", "Descrição")) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"), full_width = FALSE, position = "center") %>% column_spec(1, bold = TRUE) %>% column_spec(2, bold = TRUE, color = "white", background = "#f58723") %>% column_spec(3, width = "50em")``````{r,echo=FALSE, message=FALSE, warning=FALSE}rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio,stringdist, scales, lubridadte)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2023 , NCM e juntar as baseslibrary(arrow)dados_2023 <- read_parquet("IMEA_2023_novo.parquet")NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2023,NCM)# Filtrar soja e origem MTamostra1 = dados %>% filter(Produto == 'Soja' & UF_ORIGEM_CTE == 'MT')amostra = amostra1 %>% dplyr::filter (!UF_DESTINO_CTE == "MT")#remover valores duplicadosamostra <- amostra %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- amostra$VALR_PRODUTO %>% gsub("\\.", "", .) %>% # remove pontos de milhar gsub(",", ".", .) %>% # transforma vírgula em ponto decimal as.numeric() # converte para numérico# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- amostra$VALR_UNIDADE_COMERCIAL %>% # 1) remover pontos de milhar (literal “.”) gsub("\\.", "", .) %>% # escapa o ponto como \\. # 2) trocar vírgula decimal por ponto gsub(",", ".", .) %>% # agora converte vírgula em ponto # 3) converter texto limpo para numérico as.numeric()# quantidade de cargaamostra$QTDE_CARGA <- amostra$QTDE_CARGA %>% # 1) remover pontos de milhar (literal “.”) gsub("\\.", "", .) %>% # 2) trocar virgula decimal por ponto gsub(",", ".", .) %>% # 3) converter para numérico as.numeric() # valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO <- amostra$VALOR_PRESTACAO_SERVICO %>% # 1) remove pontos de milhar gsub("\\.", "", .) %>% # 2) troca vírgula por ponto decimal gsub(",", ".", .) %>% # 3) converte para numérico as.numeric()classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS PARA O EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))df2 = amostra#####################amostra = df2amostra <- amostra %>% filter(CODG_CFOP %in% c(6906, 6557, 6152, 6156, 6151, 6155, 6102, 6120, 6119, 6110, 6117, 6106, 6101, 6118, 6116, 6105, 6122))# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <- function(amostra) { amostra <- amostra %>% mutate(QTDE_CARGA_TON = case_when( # Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos|PESO BRUTO|PESO BASE DE CALCULO|PESO AFERIDO", ignore_case = TRUE))~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # 1 KG = 0.001 TON UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("UN", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("Soja|LITRAGEM|30000|46000|37000|VOLUME|LIQUIDO|SOLIDA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("_|,|GANEL|PB|SEMENTE|BIG BAG|DIVERSAS|BAG|15000|36000|QUIULOGRAMA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("TONELADA|TON", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON # Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA == "TON" & str_detect(TIPO_MEDIDA, regex("PESO_BRUTO", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "TON" ~ QTDE_CARGA*1, # Já está em toneladas # Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case = TRUE)) ~ QTDE_CARGA * 1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.025, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case = TRUE)) ~ QTDE_CARGA *1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case = TRUE))~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg|PESO AFERIDO|PESO DECLARADO|PESO BASE DE CALCULO|QUILOGRAMAS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("KILOGRAMAS|CAIXAS|VOLUME|LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO CUBADO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # casos de unidades UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO|GRANEL", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("LITRAGEM|PESO LIQUIDO|GALAO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Casos não mapeados ou sem peso específico TRUE ~ NA_real_ # Retorna NA para casos não tratados )) return(amostra)}# Aplicar a função de conversãoamostra2 <- converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>% filter(is.na(QTDE_CARGA_TON))amostra2 = amostra2 %>% filter(!is.na(QTDE_CARGA_TON))#-----------------------------------------------------------------------------#amostra2 <- amostra2 %>% filter(QTDE_CARGA_TON > 1)#----------------------------------------------------------------------------##-----------------------------------------------------------------------------#amostra2 <- amostra2 %>% mutate(QTDE_CARGA_TON_AJUS = case_when( MODO_TRANSPORTE == "RODOVIARIO" & QTDE_CARGA_TON> 80 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "AEREO" & QTDE_CARGA_TON > 1000 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "FERROVIARIO" & QTDE_CARGA_TON > 12000 ~ QTDE_CARGA_TON / 1000, TRUE ~ QTDE_CARGA_TON ))```## 6.2 Tratamento e resultados```{r}p1 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)boxplot(amostra2$QTDE_CARGA_TON,horizontal =TRUE,main ="Boxplot de QTDE_CARGA_TON")abline(v =c(p1, p99), col =c("red","darkgreen"), lwd =2, lty =2)```Como podemos observar no gráfico, a maioria dos registros apresenta valores relativamente baixos, porém há uma quantidade significativa de dados com valores muito elevados. No entanto, não é adequado classificá-los automaticamente como outliers, pois podem representar operações legítimas de grande porte. Diante disso, foram consideradas três alternativas para lidar com essa situação, todas baseadas no uso do método do intervalo interquartil (IQR) como critério para tratamento dos dados extremos.## 6.3 Metodo substituição interquartilEsse método é conhecido como **"substituição interquartil"**, ou mais especificamente, **"capamento por percentis"**, utilizando neste caso os percentis de 1% (P1) e 99% (P99).Em séries de dados de tonelagem, é comum surgirem valores extremamente altos — muitas vezes causados por erros de digitação ou registros anômalos — que acabam inflando artificialmente a soma total.Ao aplicar o capamento por percentis:- Um valor atípico, como **1.000.000 toneladas**, pode ser reduzido para algo mais plausível, como **20.000 toneladas**, caso esse seja o valor do percentil 99.- Da mesma forma, valores extremamente baixos, como **0,0001**, podem ser elevados até o valor correspondente ao percentil 1, por exemplo, **5 toneladas**.Esse tipo de ajuste preserva a estrutura geral dos dados, evitando distorções provocadas por valores extremos, sem simplesmente eliminar registros potencialmente válidos.```{r}p1 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# Supondo que amostra2 já tenha a coluna QTDE_CARGA_TONdf <- amostra2 %>%# 1) manter cópia íntegra antes de qualquer ajustemutate(QTDE_ORIGINAL = QTDE_CARGA_TON) %>%# 2) calcular os percentis de 1% e 99% { p1 <-quantile(.$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE) p99 <-quantile(.$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)bind_cols(., tibble(P1 = p1, P99 = p99)) } %>%# 3) cap nos percentis (entre P1 e P99)mutate(QTDE_CAP_PERCENTIL =pmin(pmax(QTDE_CARGA_TON, P1), P99),# 4) alternativa com pmin/pmax diretos (exemplo fixo)QTDE_CAP_FIXO =pmin(pmax(QTDE_CARGA_TON, 10), 10000) ) %>%# 5) opcional: remover colunas auxiliaresselect(-P1, -P99)``````{r}# Exemplo com dados agrupados por tempo (ajuste conforme seus dados)df_grouped <- df %>%group_by(DATA_EMISSAO_CTE) %>%# Substitua pela sua coluna de temposummarise(total_pct =sum(QTDE_CAP_PERCENTIL, na.rm =TRUE))ggplot(df_grouped, aes(x = DATA_EMISSAO_CTE, y = total_pct /1e6)) +geom_line(color ="steelblue", size =1) +labs(title ="Total de Carga com Capping 1-99%",x ="Período",y ="Total (Mt)") +theme_minimal()``````{r}total_pct <-sum(df$QTDE_CAP_PERCENTIL, na.rm =TRUE) # coluna a se considerarcat("Total cap 1–99% (Mt):", total_pct /1e6, "\n")```Após a aplicação desse tratamento, o valor estimado de consumo interestadual foi de 5,26 milhões de toneladas, enquanto o valor divulgado pelo site do IMEA é de 5,31 milhões de toneladas. Isso indica uma diferença de 0,05 milhão de toneladas entre a estimativa e o valor oficial.Vale ressaltar que, ao limitar valores extremos ao percentils de 1% e 99%, o método pode distorcer e distribuição original de dados.## 6.4 Método substituição pela medianaNo método de substituição pela mediana, o processo também começa com o cálculo dos percentis para identificar valores extremos. No entanto, ao invés de substituir os outliers pelos próprios valores dos percentis (como no capamento), eles são substituídos pela mediana dos dados, considerando o agrupamento por município de origem e destino. Essa abordagem permite suavizar os valores discrepantes mantendo as características específicas de cada rota, preservando padrões regionais importantes na análise.```{r}#Mediana - Metodo substituição interqualtillibrary(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(df$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(df$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular mediana por rota (origem + destino)medianas_rotas <- df %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIANA_ROTA =median(QTDE_CARGA_TON, na.rm =TRUE), .groups ="drop")# 3. Juntar a mediana por rota de volta no dataframe originaldfmed <- df %>%left_join(medianas_rotas, by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE"))# 4. Substituir valores extremos pela mediana da rotadfmed <- dfmed %>%mutate(QTDE_MEDIANA_POR_ROTA =ifelse(QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIANA_ROTA, QTDE_CARGA_TON))# 5. Verificar os somatóriostotal_original <-sum(dfmed$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(dfmed$QTDE_MEDIANA_POR_ROTA, na.rm =TRUE) # coluna de interesse``````{r}library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- dfmed %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIANA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Mediana por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)```Fazendo a substuição pela mediana, pode perceber que os dados são menos dispersos e a o valor final é de :```{r}cat("Total com mediana por rota (Mt):", total_ajustado /1e6, "\n")```O resultado estimado foi de 4,51 milhões de toneladas, o que representa uma diferença de 0,80 milhão a menos em relação aos 5,31 milhões de toneladas divulgados pelo IMEA.## 6.5 Método da Substuição pela médiaNo método de substituição pela mediana, o processo também começa com o cálculo dos percentis para identificar valores extremos. No entanto, ao invés de substituir os outliers pelos próprios valores dos percentis (como no capamento), eles são substituídos pela média dos dados, considerando o agrupamento por município de origem e destino.```{r,warning=FALSE, message=FALSE}library(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <- quantile(dfmed$QTDE_CARGA_TON, probs = 0.01, na.rm = TRUE)p99 <- quantile(dfmed$QTDE_CARGA_TON, probs = 0.99, na.rm = TRUE)# 2. Calcular média por rota (origem + destino) a partir de dfmedmedias_rotas <- dfmed %>% group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>% summarise( MEDIA_ROTA = mean(QTDE_CARGA_TON, na.rm = TRUE), .groups = "drop" )# 3. Montar defmedia a partir de dfmed, juntando a média por rotadefmedia <- df %>% left_join( medias_rotas, by = c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE") ) %>% # 4. Criar coluna com substituição de extremos pela média da rota mutate( QTDE_MEDIA_POR_ROTA = ifelse( QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIA_ROTA, QTDE_CARGA_TON ) )# 5. Verificar os somatóriostotal_original <- sum(defmedia$QTDE_CARGA_TON, na.rm = TRUE)total_ajustado <- sum(defmedia$QTDE_MEDIA_POR_ROTA, na.rm = TRUE) # coluna de interesse``````{r,warning=FALSE,message=FALSE}library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- defmedia %>% mutate(Data = as.Date(DATA_EMISSAO_CTE)) %>% # Substitua "DATA" pelo nome da sua coluna de data group_by(DATA_EMISSAO_CTE) %>% summarise(Total_Carga_Ajustada = sum(QTDE_MEDIA_POR_ROTA, na.rm = TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) + # Dividindo por 1e6 para mostrar em milhões de toneladas geom_line(color = "steelblue", linewidth = 1) + geom_point(color = "steelblue", size = 2) + labs(title = "Evolução da Carga Ajustada (Método Média por Rota)", subtitle = "Valores extremos substituídos pela mediana da rota correspondente", x = "Data", y = "Total de Carga (Milhões de Toneladas)", ) + theme_minimal() + theme(plot.title = element_text(hjust = 0.5, face = "bold"), plot.subtitle = element_text(hjust = 0.5)) + scale_y_continuous(labels = scales::comma)```Ao aplicar a substituição pela média, observamos um comportamento semelhante ao obtido com a mediana. No entanto, como a média é sensível a valores extremos, o resultado final tende a ser um pouco mais elevado.```{r}cat("Total com média por rota (Mt): ", total_ajustado /1e6, "\n") ```O resultado estimado foi de 5,78 milhões de toneladas, valor superior aos 5,31 milhões divulgados pelo IMEA, o que representa uma diferença de 0,47 milhão de toneladas.# 7.Consumo Interestadual 2024Para o ano de 2024, foi realizado exatamente o mesmo tratamento. Sendo assim, apresentamos a seguir apenas os resultados obtidos.```{r,warning=FALSE,message=FALSE,echo=FALSE}# Consumo estadual 2034rm(list = ls())setwd('Z:/Área Técnica/Rotina/Projeções/R214_Tratamento de dados/SEFAZ/TRATAMENTO ATUAL/MILHO/NOVO TRATAMENTO SAFRA COMPLETA')pacman::p_load(arrow,ggplot2,readr, readxl,tibble,lattice, stringr,dplyr,data.table, tidyr,outliers,rio,stringdist, scales, lubridadte)#---------------------------------------------------------##---------------------------------------------------------##carregar dados de 2023 , NCM e juntar as baseslibrary(arrow)dados_2024 <- read_parquet("IMEA_2024_novo.parquet")NCM <- read_excel("NCM.xlsx")|> dplyr:: filter(Produto=="Milho"|Produto=="Soja" | Produto=="Algodão em pluma") |> # selecionar os produtos para o tratamento dplyr::rename(NUMR_NCM='NCM')dados <- dplyr::inner_join(dados_2024,NCM)# Filtrar soja e origem MTamostra1 = dados %>% filter(Produto == 'Soja' & UF_ORIGEM_CTE == 'MT')amostra = amostra1 %>% dplyr::filter (!UF_DESTINO_CTE == "MT")#remover valores duplicadosamostra <- amostra %>% distinct()# data de emissão (as.date)amostra$DATA_EMISSAO_CTE <- as.Date(amostra$DATA_EMISSAO_CTE, format = "%d/%m/%Y")# valor do produto amostra$VALR_PRODUTO <- amostra$VALR_PRODUTO %>% gsub("\\.", "", .) %>% # remove pontos de milhar gsub(",", ".", .) %>% # transforma vírgula em ponto decimal as.numeric() # converte para numérico# valor unidade comercial amostra$VALR_UNIDADE_COMERCIAL <- amostra$VALR_UNIDADE_COMERCIAL %>% # 1) remover pontos de milhar (literal “.”) gsub("\\.", "", .) %>% # escapa o ponto como \\. # 2) trocar vírgula decimal por ponto gsub(",", ".", .) %>% # agora converte vírgula em ponto # 3) converter texto limpo para numérico as.numeric()# quantidade de cargaamostra$QTDE_CARGA <- amostra$QTDE_CARGA %>% # 1) remover pontos de milhar (literal “.”) gsub("\\.", "", .) %>% # 2) trocar virgula decimal por ponto gsub(",", ".", .) %>% # 3) converter para numérico as.numeric()# valor prestação de serviçoamostra$VALOR_PRESTACAO_SERVICO <- amostra$VALOR_PRESTACAO_SERVICO %>% # 1) remove pontos de milhar gsub("\\.", "", .) %>% # 2) troca vírgula por ponto decimal gsub(",", ".", .) %>% # 3) converte para numérico as.numeric()classificar_cfop <- function(cfop) { # Converte para string e extrai o primeiro dígito primeiro_digito <- str_sub(as.character(cfop), 1, 1) # Classifica com base no primeiro dígito case_when( primeiro_digito == 1 ~ "ENTRADAS DO ESTADO", primeiro_digito == 2 ~ "ENTRADAS DE OUTROS ESTADOS", primeiro_digito == 3 ~ "ENTRADAS DO EXTERIOR", primeiro_digito == 5 ~ "SAÍDAS PARA O ESTADO", primeiro_digito == 6 ~ "SAÍDAS PARA OUTROS ESTADOS", primeiro_digito == 7 ~ "SAÍDAS PARA O EXTERIOR", TRUE ~ "OUTROS" # Caso padrão para valores inesperados )}# Aplicar ao datasetamostra <- amostra %>% filter(!is.na(CODG_CFOP)) %>% # Remove linhas com CODG_CFOP NA mutate(CLASSIFICACAO_CFOP = classificar_cfop(CODG_CFOP))df2 = amostra#####################amostra = df2amostra <- amostra %>% filter(CODG_CFOP %in% c(6906, 6557, 6152, 6156, 6151, 6155, 6102, 6120, 6119, 6110, 6117, 6106, 6101, 6118, 6116, 6105, 6122))# Função para converter QTDE_CARGA para toneladasconverter_para_toneladas <- function(amostra) { amostra <- amostra %>% mutate(QTDE_CARGA_TON = case_when( # Regras para UNIDADE_MEDIDA == "KG" UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|KILO|PESO|CARGA|BRUTO|AFERIDO|TAXADO|CUBADO|COBRADO|DECLARADO|GRANEL|BASE|Quilograma|Quilos|PESO BRUTO|PESO BASE DE CALCULO|PESO AFERIDO", ignore_case = TRUE))~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # 1 KG = 0.001 TON UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kilo|KILO|quilo|QUILO|SOJA EM GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("SOLIDO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("UN", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("GRAOS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("Soja|LITRAGEM|30000|46000|37000|VOLUME|LIQUIDO|SOLIDA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("_|,|GANEL|PB|SEMENTE|BIG BAG|DIVERSAS|BAG|15000|36000|QUIULOGRAMA", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "KG" & str_detect(TIPO_MEDIDA, regex("TONELADA|TON", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON # Regras para UNIDADE_MEDIDA == "TON"e UNIDADE_MEDIDA == "TON" & str_detect(TIPO_MEDIDA, regex("PESO_BRUTO", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "TON" ~ QTDE_CARGA*1, # Já está em toneladas # Regras para UNIDADE_MEDIDA == "UNIDADE" UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("QUILO|KG|GRANEL|A GRANEL", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 QUILO = 0.001 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACAS 25 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACAS 25 KG = 0.025 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("SACOS 50 KG", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # 1 SACOS 50 KG = 0.05 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("ton|TON|Ton|T|Tonelada|tonelada|TONELADA|Toneladas|TONELADAS|toneladas", ignore_case = TRUE)) ~ QTDE_CARGA * 1, # 1 BIG-BAG = 1 TON UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("BIG-BAG", ignore_case = TRUE)) ~ QTDE_CARGA * 1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Volume|Volumes|VOLUME|VOLUMES|volume|volumes", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Fardo|fardo|Fardos|fardos|FARDO|FARDOS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("sacos|Sacos|SACOS|SC|Saco|SACO|Saca|Sacas|saca|sacas|SACA|SACAS", ignore_case = TRUE)) ~ QTDE_CARGA * 0.025, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("Unidade|unidade|Unidades|unidades|UNIDADE|UNIDADES", ignore_case = TRUE)) ~ QTDE_CARGA *1, UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("CAIXAS|CAIXA|caixas|caixa", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "UNIDADE" & str_detect(TIPO_MEDIDA, regex("KG|kg|Kg|Kilo|", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Regras para UNIDADE_MEDIDA == "M3" UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("M3|CUBAGEM|METROS CUBICOS|METRAGEM CUBICA|METRO CUBICO", ignore_case = TRUE))~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO BRUTO|PESO_BRUTO|peso bruto|peso_bruto|Peso Bruto|PESO LIQUIDO|kg|PESO AFERIDO|PESO DECLARADO|PESO BASE DE CALCULO|QUILOGRAMAS", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("KILOGRAMAS|CAIXAS|VOLUME|LITRAGEM", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "M3" & str_detect(TIPO_MEDIDA, regex("PESO CUBADO", ignore_case = TRUE)) ~ QTDE_CARGA * 0.001, # casos de unidades UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("KILO|PESO BRUTO|GRANEL", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), UNIDADE_MEDIDA == "LITROS" & str_detect(TIPO_MEDIDA, regex("LITRAGEM|PESO LIQUIDO|GALAO", ignore_case = TRUE)) ~ ifelse(QTDE_CARGA > 1000, QTDE_CARGA * 0.001, QTDE_CARGA * 1), # Casos não mapeados ou sem peso específico TRUE ~ NA_real_ # Retorna NA para casos não tratados )) return(amostra)}# Aplicar a função de conversãoamostra2 <- converter_para_toneladas(amostra)nao_convertidos <- amostra2 %>% filter(is.na(QTDE_CARGA_TON))amostra2 = amostra2 %>% filter(!is.na(QTDE_CARGA_TON))#-----------------------------------------------------------------------------#amostra2 <- amostra2 %>% filter(QTDE_CARGA_TON > 1)#----------------------------------------------------------------------------##write.csv2(df,"C:/Users/maria.muniz/Desktop/dados/X.csv")#-----------------------------------------------------------------------------#amostra2 <- amostra2 %>% mutate(QTDE_CARGA_TON_AJUS = case_when( MODO_TRANSPORTE == "RODOVIARIO" & QTDE_CARGA_TON> 80 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "AEREO" & QTDE_CARGA_TON > 1000 ~ QTDE_CARGA_TON / 1000, MODO_TRANSPORTE == "FERROVIARIO" & QTDE_CARGA_TON > 12000 ~ QTDE_CARGA_TON / 1000, TRUE ~ QTDE_CARGA_TON ))```## 7.1 Método substituição interquartil```{r}# Calcular os percentisp1 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(amostra2$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)#Metodo substituição interqualtil# Supondo que amostra2 já tenha a coluna QTDE_CARGA_TONdf <- amostra2 %>%# 1) manter cópia íntegra antes de qualquer ajustemutate(QTDE_ORIGINAL = QTDE_CARGA_TON) %>%# 2) calcular os percentis de 1% e 99% { p1 <-quantile(.$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE) p99 <-quantile(.$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)bind_cols(., tibble(P1 = p1, P99 = p99)) } %>%# 3) cap nos percentis (entre P1 e P99)mutate(QTDE_CAP_PERCENTIL =pmin(pmax(QTDE_CARGA_TON, P1), P99),# 4) alternativa com pmin/pmax diretos (exemplo fixo)QTDE_CAP_FIXO =pmin(pmax(QTDE_CARGA_TON, 10), 10000) ) %>%# 5) opcional: remover colunas auxiliaresselect(-P1, -P99)# Agora você tem:# - QTDE_ORIGINAL : valores sem cap (para somatório total)# - QTDE_CAP_PERCENTIL : valores capados entre 1º e 99º percentil# - QTDE_CAP_FIXO : exemplo de cap fixo entre 10 e 1000# Somatórios para comparaçãototal_orig <-sum(df$QTDE_ORIGINAL, na.rm =TRUE)total_pct <-sum(df$QTDE_CAP_PERCENTIL, na.rm =TRUE) # coluna a se considerartotal_fixo <-sum(df$QTDE_CAP_FIXO, na.rm =TRUE)``````{r}# Exemplo com dados agrupados por tempo (ajuste conforme seus dados)df_grouped <- df %>%group_by(DATA_EMISSAO_CTE) %>%# Substitua pela sua coluna de temposummarise(total_pct =sum(QTDE_CAP_PERCENTIL, na.rm =TRUE))ggplot(df_grouped, aes(x = DATA_EMISSAO_CTE, y = total_pct /1e6)) +geom_line(color ="steelblue", size =1) +labs(title ="Total de Carga com Capping 1-99%",x ="Período",y ="Total (Mt)") +theme_minimal()```Aplicando o método substuição interquartil, observamos o seguinte comportamento na série de dados, resultando em um valor estimado de consumo interestadual de:```{r}sum(df$QTDE_CAP_PERCENTIL)/1000000```8.61 milhões para 2024 , valor consideravelmente acima dos 2,10 milhões divulgados pelo Imea.## 7.2 Método substituição pela mediana```{r}#Mediana - Metodo substituição interqualtillibrary(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(df$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(df$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular mediana por rota (origem + destino)medianas_rotas <- df %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIANA_ROTA =median(QTDE_CARGA_TON, na.rm =TRUE), .groups ="drop")# 3. Juntar a mediana por rota de volta no dataframe originaldfmed <- df %>%left_join(medianas_rotas, by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE"))# 4. Substituir valores extremos pela mediana da rotadfmed <- dfmed %>%mutate(QTDE_MEDIANA_POR_ROTA =ifelse(QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIANA_ROTA, QTDE_CARGA_TON))# 5. Verificar os somatóriostotal_original <-sum(dfmed$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(dfmed$QTDE_MEDIANA_POR_ROTA, na.rm =TRUE) # coluna de interesse``````{r}library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- dfmed %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIANA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Mediana por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)```No método da mediana novamente temos os dados mais estabilizados, e o valor de :```{r}cat("Total com mediana por rota (Mt):", total_ajustado /1e6, "\n")```2.86 Milhões de tonelas, próximo ao valor de 2.10 divulgados pelo imea.## 7.3 Método substituição pela média```{r}library(dplyr)# 1. Calcular os percentis globais para identificar extremosp1 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.01, na.rm =TRUE)p99 <-quantile(dfmed$QTDE_CARGA_TON, probs =0.99, na.rm =TRUE)# 2. Calcular média por rota (origem + destino) a partir de dfmedmedias_rotas <- dfmed %>%group_by(CODG_MUNICIPIO_ORIGEM_IBGE, CODG_MUNICIPIO_DESTINO_IBGE) %>%summarise(MEDIA_ROTA =mean(QTDE_CARGA_TON, na.rm =TRUE),.groups ="drop" )# 3. Montar defmedia a partir de dfmed, juntando a média por rotadefmedia <- df %>%left_join( medias_rotas,by =c("CODG_MUNICIPIO_ORIGEM_IBGE", "CODG_MUNICIPIO_DESTINO_IBGE") ) %>%# 4. Criar coluna com substituição de extremos pela média da rotamutate(QTDE_MEDIA_POR_ROTA =ifelse( QTDE_CARGA_TON < p1 | QTDE_CARGA_TON > p99, MEDIA_ROTA, QTDE_CARGA_TON ) )# 5. Verificar os somatóriostotal_original <-sum(defmedia$QTDE_CARGA_TON, na.rm =TRUE)total_ajustado <-sum(defmedia$QTDE_MEDIA_POR_ROTA, na.rm =TRUE) # coluna de interesse``````{r}library(ggplot2)library(dplyr)# 1. Primeiro vamos agregar os dados por período (assumindo que existe uma coluna de data)# Caso sua coluna de data tenha outro nome, ajuste abaixodf_grafico <- defmedia %>%mutate(Data =as.Date(DATA_EMISSAO_CTE)) %>%# Substitua "DATA" pelo nome da sua coluna de datagroup_by(DATA_EMISSAO_CTE) %>%summarise(Total_Carga_Ajustada =sum(QTDE_MEDIA_POR_ROTA, na.rm =TRUE))# 2. Criar o gráfico de linhaggplot(df_grafico, aes(x = DATA_EMISSAO_CTE, y = Total_Carga_Ajustada/1e6)) +# Dividindo por 1e6 para mostrar em milhões de toneladasgeom_line(color ="steelblue", linewidth =1) +geom_point(color ="steelblue", size =2) +labs(title ="Evolução da Carga Ajustada (Método Média por Rota)",subtitle ="Valores extremos substituídos pela mediana da rota correspondente",x ="Data",y ="Total de Carga (Milhões de Toneladas)", ) +theme_minimal() +theme(plot.title =element_text(hjust =0.5, face ="bold"),plot.subtitle =element_text(hjust =0.5)) +scale_y_continuous(labels = scales::comma)```Novamente, fazendo a substuição pela média, temos uma dispersão maior e o valor final de:```{r}cat("Total com média por rota (Mt): ", total_ajustado /1e6, "\n") ```# 8.ConclusõesPodemos concluir que a metodologia adotada tem se mostrado eficaz, especialmente para os dados de exportação e de consumo dentro do estado de Mato Grosso. No entanto, no que diz respeito ao consumo interestadual, a diversidade de CFOPs com características distintas exige uma avaliação mais criteriosa entre os três métodos apresentados, a fim de garantir maior precisão na estimativa final.```{r,warning=FALSE,message=FALSE,echo=FALSE}library(gt)library(tidyverse)library(kableExtra)# Criando os dadosdados <- tibble( Categoria = c("Exportação", "Consumo MT", "Consumo INER(Interquartil)", "Consumo INER (Mediana)", "Consumo INER (Média)"), `Estimado 2023` = c(28.34, 11.98, 5.26, 4.51, 5.78), `Real 2023` = c(28.34, 11.76, 5.31, 5.31, 5.31), `Diferença 2023` = c(0.00136, 0.21901, -0.047894, -0.804774, 0.471895), `Estimado 2024` = c(23.33, 12.37, 8.61, 2.86, 4.35), `Real 2024` = c(24.73, 12.68, 2.10, 2.10, 2.10), `Diferença 2024` = c(-1.39605, -0.31285, 6.51355, 0.757583, 2.246559))dados %>% kable("html", align = 'c', digits = 2) %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE) %>% add_header_above(c(" " = 1, "2023" = 3, "2024" = 3)) %>% row_spec(0, bold = TRUE) %>% column_spec(1, bold = TRUE) %>% column_spec(c(4,7), color = "white", background = spec_color(dados$`Diferença 2023`, end = 0.7)) %>% column_spec(c(7), color = "white", background = spec_color(dados$`Diferença 2024`, end = 0.7)) %>% footnote(general = "Valores em milhões de unidades")```