library(readxl)
library(openxlsx)
library(dplyr)
library(magrittr)
library(tidyr)
library(tidyverse)
library(stringr)
library(DT)
library(formattable)
library(kableExtra)
library(echarts4r)

disciplinas <- read_excel("./dados/Disciplinas Graduação 2023.xlsx")
disciplinas_pos_2023 <- read_excel("./dados/Disciplinas Pós-graduação 2023.xlsx")
lista_deptos <- read_excel("./dados/lista_deptos.xlsx")
relacao <- read_excel("./dados/Relação disciplinas graduação.xlsx")
docentes <- read_excel("./dados/08 Docentes 2023 MODALOC.xlsx")
particao_depart <- read_excel("./dados/Partição depart.xlsx")
# tabela que informa se a producao conta ou nao para o modaloc:
tipo_producao <- read_excel("./dados/TipoProdução.xlsx")
# producao
producao_2023 <- read_excel("./dados/Produção 2023.xlsx")

# modaloc modelo antigo Priscila
modaloc_priscila <- read_excel("./dados/Modaloc 09 com bônus.xlsx")

Introdução

Proposta de modelo de alocação de recursos entre departamentos da UFPE - 2025.

Dados

Para o cálculo do novo modelo, partimos dos dados utilizados em 2025, conforme a Tabela abaixo:

Dados Arquivo Fonte
Disciplinas Ofertadas na Graduação - 2023 Disciplinas Graduação 2023.xlsx STI
Lista de Departamentos lista_deptos.xlsx Elaboração própria
Relação de Disciplinas da Graduação Relação disciplinas graduação.xlsx Elaboração própria
Lista de Docentes 08 Docentes 2023 MODALOC.xlsx STI
Produção Bibliográfica Produção 2023.xlsx ???

Pré-processamento dos dados

Foram necessárias algumas correções nos dados, bem como cruzamento de tabelas.

OBS: Para o MODALOC, os centros CCJ, CCM e o CIN são vistos como uma única unidade.

Pré-Processamento Docente

Nos dados de docentes, primeiramente adicionamos o regime, lotação e cargo dos docentes (este último é adicionado para filtrarmos os docentes visitantes e substitutos, que não entram no Modaloc). Removemos do cálculo o Colégio de Aplicação.

# docentes 01

#docentes <- read_excel("./dados/08 Docentes 2023 MODALOC.xlsx")
regime <- read_excel("./dados/Regime.xlsx")
lotacao <- read_excel("./dados/Lotação docentes.xlsx")
cargos <- read_excel("./dados/CargosEfetivo.xlsx")

# atualizando pesos 2025
pesos_depto <- read_excel("./dados/pesos_depto.xlsx",
                          col_types = c("text", "numeric", "numeric",
                                        "skip", "skip"))

lotacao %<>% left_join(pesos_depto %>%
                         select(Departamentos2, PESO2025), by="Departamentos2")


docentes01 <- docentes %>%
  # LEFT JOIN com a tabela de regime
  left_join(regime, by = c("Regime" = "RegimeDeTrabalho")) %>%
  
  # LEFT JOIN com a tabela de lotação
  left_join(lotacao, 
            by = c("Departamentos" = "Departamentos", 
                   "Centro" = "Centro", 
                   "CAMPUS" = "CAMPUS")) %>%
  
  # LEFT JOIN com a tabela de cargos
  left_join(cargos, by = c("Cargo" = "Cargo")) %>%
  
  # Agrupamento (mesmo que não use summarise, por semelhança com GROUP BY)
  group_by(CAMPUS, Centro2, Centro_cota, Departamentos2, Lotação2, RT, Efetivo, CPF, PESO2025) %>%
  
  # Filtro HAVING
  filter(Departamentos2 != "Colégio de Aplicação") %>%
  
  # Seleção das colunas finais
  select(CAMPUS, Centro = Centro2, Centro_cota, Departamentos2, Lotação2, 
         RT, Efetivo, CPF, PESO = PESO2025)



docentes02 <- docentes01 %>%
  # Filtro para apenas efetivos
  filter(Efetivo == 1) %>%
  
  # Agrupamento pelas mesmas colunas
  group_by(CAMPUS, Centro_cota, Centro, Departamentos2, Lotação2, Efetivo, PESO) %>%
  
  # Soma de RT
  summarise(Quant = sum(RT, na.rm = TRUE), .groups = "drop")

Dividimos o Modaloc em três grupos de indicadores: Dimensão, Qualidade e Produção.

  • Dimensão: grupo de indicadores que mede o esforço docente, relação aluno/professor (graduação e na pós-graduação) e Área Construída por departamento.
  • Qualidade: indicadores de qualidade dos cursos de graduação e pós-graduação.
  • Produção: indicadores baseados na produção acadêmica dos departamentos, contemplando ensino, pesquisa e extensão.

Dimensão

Graduação

Esforço Docente

O esforço docente em uma disciplina é dado pelo produto da carga horária pelo número de matriculados. Consequentemente, o esforço docente de um departamento consiste na soma do esforço docente das disciplinas ofertadas por este departamento.

Nos dados, desconsideramos disciplinas de TCC e Estágio. Além disso, houve disciplinas repetidas nos dados, isto é, disciplinas com o mesmo nome, docente, período, etc. Neste caso, removemos estas duplicatas para não inflacionar o esforço docente de alguns departamentos.

Depois de computar o esforço docente por departamento, padronizamos a medida. Assim, a variável ESFORCO_DOCENTE_DEPTO_PADRONIZADO representa o percentual de esforço docente de um departamento em relação à soma dos esforços docentes de todos os departamentos.

Finalmente, criamos um ranking de esforço docente para ordenar os departamentos de acordo com esta medida.

# numero alunos * ch dado por cada departamento.

disciplinas %>%
  # JOIN com a relação de disciplinas
  left_join(relacao, 
            by = c("nome_disc" = "DISCIPLINA", 
                   "id_disc" = "COD_DISC"), relationship = "many-to-many") %>%
  
  # JOIN com a base de docentes (pelo CPF numérico)
  left_join(docentes01, 
            by = c("cpf_num" = "CPF")) %>%
  
  # Filtro equivalente ao HAVING (aplicado após o join)
  filter(!is.na(Lotação2)) %>%
  
  # Agrupamento
  group_by(CAMPUS, Centro, Centro_cota, Departamentos2, Lotação2,
           nome_oficial, cpf, cpf_num, unidade_disciplina, perd_letv,
           id_disc, ch_total, Disciplinas_dif, PESO) %>%
  
  # Agregação
  summarise(qtd_matr = max(qtd_matr, na.rm = TRUE), 
            .groups = "drop") -> disciplinas


# removendo disciplinas repetidas (distinct)
disciplinas %>% 
  group_by(unidade_disciplina, perd_letv, id_disc, ch_total, qtd_matr) %>% 
  filter(n()>1) %>% 
  select(-c(nome_oficial, cpf_num, cpf)) %>% distinct -> disciplinas_repetidas

# pegando disciplinas unicas
disciplinas %>% 
  group_by(unidade_disciplina, perd_letv, id_disc, ch_total, qtd_matr) %>% 
  filter(n()==1) %>% 
  select(-c(nome_oficial, cpf_num, cpf)) -> disciplinas_unicas

# total de disciplinas:
disciplinas_unicas %>% bind_rows(disciplinas_repetidas) -> disciplinas_total

disciplinas_total %>%
  mutate(ESFORCO_DOCENTE_i = ch_total*qtd_matr) %>%
  filter(Disciplinas_dif != 1) %>% 
  group_by(Departamentos2, Centro) %>% 
  summarise(ESFORCO_DOCENTE_DEPTO = sum(ESFORCO_DOCENTE_i)) %>% 
  arrange(desc(ESFORCO_DOCENTE_DEPTO)) %>% ungroup %>% 
  mutate(ESFORCO_DOCENTE_DEPTO_PADRONIZADO = 
           ESFORCO_DOCENTE_DEPTO/sum(ESFORCO_DOCENTE_DEPTO),
         rank_esforco_padronizado=
           dense_rank(desc(ESFORCO_DOCENTE_DEPTO_PADRONIZADO))) %>% 
  rename("Departamento" = Departamentos2) %>% 
  relocate(Centro, .before = "Departamento") -> esforco_docente

datatable(esforco_docente, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(columns=c('ESFORCO_DOCENTE_DEPTO', 
                        'ESFORCO_DOCENTE_DEPTO_PADRONIZADO'), digits=3) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('ESFORCO_DOCENTE_DEPTO_PADRONIZADO',
              background = styleColorBar(range(
                esforco_docente$ESFORCO_DOCENTE_DEPTO_PADRONIZADO), 'lightgreen'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center')

Relação Aluno/Professor

Para computar a Relação Aluno/Professor de um departamento, selecionamos as disciplinas ministradas por docentes efetivos lotados naquele departamento e somamos o total de matrículas. Em seguida, dividimos o número de matrículas pelo número de docentes efetivos lotados no departamento (número obtido a partir da tabela de docentes (08 Docentes 2023 MODALOC.xlsx).

Note que computamos, na prática, o total de matrículas por docente e não o total de alunos, já que a maioria dos alunos vai ter matrícula em mais de uma disciplina. É natural, então, pensar que um aluno matriculado em mais disciplinas represente mais trabalho do ponto de vista dos docentes.

IMPORTANTE: no Modaloc atual, existe um peso dos alunos por departamento definido pela gestão. Nesta proposta de modelo, apresentamos a Relação Aluno/Professor de duas formas, com os pesos e sem os pesos. Na Tabela abaixo, temos as duas colunas: Rap e Rap_PESO, assim como seus respectivos valores padronizados (em percentual do total) e os rankings. Notamos que há uma diferença importante entre Rap e Rap_PESO, resultado dos pesos adotados para os alunos dos departamentos. Por exemplo, um peso 4,5 mais que quadruplica o número de matrículas de um departamento, impactando severamente no Rap.

# removendo disciplinas repetidas (distinct)
disciplinas %>%
  group_by(unidade_disciplina, perd_letv, id_disc, 
           ch_total, qtd_matr, PESO) %>%
  filter(n()>1, Disciplinas_dif!=1) %>%
  select(-c(nome_oficial, cpf)) %>% distinct -> disciplinas_repetidas_rap

disciplinas_repetidas_rap %>% 
  group_by(Centro, Departamentos2,
    perd_letv, id_disc, qtd_matr, PESO) %>% 
  summarise(n_docentes=n()) %>% 
  filter(qtd_matr == max(qtd_matr)) -> disciplinas_repetidas_rap

# pegando disciplinas unicas
disciplinas %>%
  group_by(unidade_disciplina, perd_letv, id_disc, 
           ch_total, qtd_matr, PESO) %>%
  filter(n()==1, Disciplinas_dif!=1) %>%
  select(-c(nome_oficial, cpf)) -> disciplinas_unicas_rap

disciplinas_unicas_rap %>% 
  group_by(Centro, Departamentos2,
           perd_letv, id_disc, qtd_matr, PESO) %>% 
  summarise(n_docentes=n()) %>% 
  filter(qtd_matr == max(qtd_matr)) -> disciplinas_unicas_rap

# total de disciplinas:
disciplinas_unicas_rap %>%
bind_rows(disciplinas_repetidas_rap) -> disciplinas_total_rap

# total de docentes por departamento:
docentes01 %>% filter(Efetivo==1) %>% 
  distinct(CPF) %>% 
  group_by(Departamentos2) %>% 
  summarise(total_docentes=n()) -> docentes_por_depto

disciplinas_total_rap %>% group_by(Centro, Departamentos2) %>% 
  mutate(qtd_matrPESO = qtd_matr*PESO) %>% 
  summarise(PESO = max(PESO),
            total_matriculas_PESO = sum(qtd_matrPESO),
            total_matriculas = sum(qtd_matr), 
  ) %>%
  left_join(docentes_por_depto) %>% 
  ungroup %>% 
  mutate(rap_PESO = total_matriculas_PESO/total_docentes,
         rap_padronizado_PESO = rap_PESO/sum(rap_PESO),
         rap = total_matriculas/total_docentes,
         rap_padronizado = rap/sum(rap),
         rank_rap_padronizado=dense_rank(desc(rap_padronizado)),
         rank_rap_padronizado_PESO=dense_rank(desc(rap_padronizado_PESO))
  ) %>% 
  rename("Departamento" = Departamentos2) -> relacao_aluno_professor


# imprimir tabela 
datatable(relacao_aluno_professor, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(columns=c('rap_PESO', 'rap_padronizado_PESO',
                        'rap', 'rap_padronizado'), digits=3) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('rap_padronizado',
              background = styleColorBar(range(relacao_aluno_professor$rap_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('rap_padronizado_PESO',
              background = styleColorBar(range(relacao_aluno_professor$rap_padronizado_PESO), 'lightgreen'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') 

Pós-Graduação

Realizamos para a pós-graduação o mesmo procedimento realizado na graduação, calculando o Esforço Docente do departamento como a soma dos esforços docentes em disciplinas de pós-graduação nas disciplinas ministradas por docentes lotados no departamento.

# pos01

pos01 <- disciplinas_pos_2023 %>%
  group_by(unidade_disciplina, perd_letv, id_disc, nome_disc, ch_total, qtd_matr) %>%
  summarise(
    Quant = n(),
    .groups = "drop"
  ) %>%
  mutate(
    Prop_doc = 1 / Quant
  )

# pos02

pos02 <- disciplinas_pos_2023 %>%
  left_join(docentes01, by = c("cpf_num" = "CPF")) %>% 
  left_join(pos01, by = c(
    "unidade_disciplina", "perd_letv", "id_disc", "nome_disc", "ch_total", "qtd_matr"
  )) %>%
  filter(!is.na(Lotação2)) %>%
  mutate(
    CH = ch_total * Prop_doc,
    AHGRi = CH * qtd_matr
  ) %>%
  select(
    CAMPUS, Centro, Centro_cota, Departamentos2, Lotação2,
    nome_oficial, cpf, cpf_num, unidade_docente, unidade_disciplina,
    perd_letv, id_disc, nome_disc,
    CH_TOTAL = ch_total,
    MAT = qtd_matr,
    Quant, Prop_doc, CH, AHGRi, PESO
  )

Esforço Docente

Para os dados de disciplinas da pós-graduação, existe a possibilidade de uma disciplina ser ministrada por mais de um docente. Neste caso, o esforço docente na disciplina fica dividido pela quantidade de docentes.

No mais, o esforço docente na disciplina é dado pela carga horária multiplicada pela quantidade de matriculados. Para o departamento, o esforço docente será dado pela soma de esforço docente em disciplinas ofertadas pelo departamento. Novamente, a medida foi padronizada e o ranking indica os departamentos com maior esforço na pós-graduação.

pos02 %>%
  mutate(ESFORCO_DOCENTE_i = AHGRi) %>%
  group_by(Departamentos2, Centro) %>% 
  summarise(ESFORCO_DOCENTE_DEPTO_POS = sum(ESFORCO_DOCENTE_i)) %>% 
  arrange(desc(ESFORCO_DOCENTE_DEPTO_POS)) %>% ungroup %>% 
  mutate(ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS = 
           ESFORCO_DOCENTE_DEPTO_POS/sum(ESFORCO_DOCENTE_DEPTO_POS),
         rank_ESFORCO_PADRONIZADO=dense_rank(desc(ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS))) %>% 
  rename("Departamento" = Departamentos2) %>% 
  relocate(Centro, .before = "Departamento") -> esforco_docente_POS
  
# imprime tabela
datatable(esforco_docente_POS, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(columns=c('ESFORCO_DOCENTE_DEPTO_POS', 
                        'ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS'), digits=3) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS',
              background = styleColorBar(range(
                esforco_docente_POS$ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS), 'lightgreen'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center')

Relação Aluno/Professor

Para a pós-graduação, também computamos o número de matrículas por docente efetivo. Note que consideramos o total de docentes lotados no departamento, não fazendo distinção entre os docentes que ministram disciplinas na graduação ou na pós-graduação. Também foram apresentados os valores considerando os pesos atribuidos pela gestão aos departamentos, do mesmo modo que foi feito nos dados da graduação.

# Relacao Aluno/Professor

pos02 %>% 
  group_by(Centro, Departamentos2,
           perd_letv, id_disc, MAT, PESO) %>% 
  summarise(n_docentes_POS=n()) %>% 
  filter(MAT == max(MAT)) -> disciplinas_rap_POS


disciplinas_rap_POS %>% group_by(Centro, Departamentos2) %>% 
  mutate(qtd_matrPESO_POS = MAT*PESO) %>% 
  summarise(PESO_POS = max(PESO),
            total_matriculas_PESO_POS = sum(qtd_matrPESO_POS),
            total_matriculas_POS = sum(MAT), 
            #total_docentes_POS = sum(n_docentes_POS)
            ) %>% 
  left_join(docentes_por_depto) %>%
  ungroup %>% 
  mutate(rap_PESO_POS = total_matriculas_PESO_POS/total_docentes,
         rap_padronizado_PESO_POS = rap_PESO_POS/sum(rap_PESO_POS),
         rap_POS = total_matriculas_POS/total_docentes,
         rap_padronizado_POS = rap_POS/sum(rap_POS),
         rank_rap_padronizado_POS=dense_rank(desc(rap_padronizado_POS)),
         rank_rap_padronizado_PESO_POS=dense_rank(desc(rap_padronizado_PESO_POS))
  ) %>% rename("Departamento" = Departamentos2) -> relacao_aluno_professor_POS

# imprimir tabela 
datatable(relacao_aluno_professor_POS, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(columns=c('rap_PESO_POS', 'rap_padronizado_PESO_POS',
                        'rap_POS', 'rap_padronizado_POS'), digits=3) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('rap_padronizado_POS',
              background = styleColorBar(range(relacao_aluno_professor_POS$rap_padronizado_POS), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('rap_padronizado_PESO_POS',
              background = styleColorBar(range(relacao_aluno_professor_POS$rap_padronizado_PESO_POS), 'lightgreen'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') 

Área Construída

Cancelado por falta de dados!

Qualidade

Os indicadores de qualidade utilizados serão o índice de qualificação do corpo docente, calculado por departamento, a avaliação dos cursos de graduação e pós-graduação e a Taxa de Sucesso na Graduação (TSG). No caso da avaliação e da TSG, os dados são compilados por Centro e a cada departamento subordinado é atribuida a nota média da avaliação.

IQCD

O Índice de Qualificação do Corpo Docente é calculado pela média ponderada pela qualificação dos docentes de um departamento.

# calculado por Inacio
IQCD <- read_excel("./dados/IQCD.xlsx", col_types = c("text", 
                                              "text", "text", "text", 
                                              "text", "numeric","numeric"))

IQCD %>% as.data.frame() %>% 
  filter(CAMPUS != "Centro", Departamentos2 != "Colégio de Aplicação") %>% 
  mutate(IQCD_padronizado = IQDC/sum(IQDC)) %>%
  select("Departamento" = Departamentos2, "Centro" = Centro2, 
         IQCD_padronizado) %>% 
  mutate(rank_IQCD_padronizado=dense_rank(desc(IQCD_padronizado))) %>% 
  relocate(Centro, .before = "Departamento") -> Qualidade

Avaliação dos Cursos

A cada departamento é atribuída a nota média da avaliação dos cursos vinculados ao centro.

# calculado por Inacio
indicadores_avaliacao <- read_excel("./dados/Indicadores de Avaliação.xlsx")

indicadores_avaliacao %<>% select(Centro, "media_aval_grad"=`Média AVAL Grad`, 
                                  "media_aval_POS" = `Média AVAL Pós`)

Taxa de Sucesso na Graduação (TSG)

Novamente, como os dados de taxa de sucesso na graduação são calculados por curso, e não por departamento, vamos atribuir a cada departamento a média da TSG do centro ao qual ele está vinculado. A tabela abaixo mostra o IQCD, as avaliações e a TSG assim obtidas:

TSG <- read_excel("./dados/Taxa de Sucesso 2023 - Modaloc.xlsx")

TSG %<>% select(Centro, "TSG_media"=`Média Tx de Sucesso`) 

Qualidade %<>% 
  left_join(indicadores_avaliacao, by=c("Centro")) %>% 
  left_join(TSG, by=c("Centro")) %>% 
  mutate(media_aval_grad_padronizado = media_aval_grad/sum(media_aval_grad),
         media_aval_POS_padronizado = media_aval_POS/sum(media_aval_POS),
         TSG_media_padronizado = TSG_media/sum(TSG_media)) 


# imprimir tabela 
datatable(Qualidade, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('IQCD_padronizado',
              background = styleColorBar(range(Qualidade$IQCD_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('media_aval_grad_padronizado',
              background = styleColorBar(range(Qualidade$media_aval_grad_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('media_aval_POS_padronizado',
              background = styleColorBar(range(Qualidade$media_aval_POS_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('TSG_media_padronizado',
              background = styleColorBar(range(Qualidade$TSG_media_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') 

Produção

Produção Bibliográfica

Cruzando os dados de publicações com a lotação dos docentes, conseguimos atribuir a produção a um departamento. Desta forma, a produção do departamento consiste na soma das publicações cujos autores são docentes ligados àquele departamento. Novamente, padronizamos os dados e rankeamos os departamentos considerando a produção.

producao01 <- producao_2023 %>%
  left_join(docentes01, by = c("cpf_num" = "CPF")) %>%
  left_join(tipo_producao, by = c("tipo_producao" = "tipo_producao")) %>%
  filter(!is.na(Departamentos2)) %>% 
  select(
    CAMPUS,
    Centro,
    Departamentos2,
    Lotação2,
    cpf,
    cpf_num,
    nome_oficial,
    titulo_producao,
    tipo_producao,
    Prod_Modaloc
  )

producao02 <- producao01 %>%
  group_by(CAMPUS, Centro, Departamentos2, Lotação2) %>%
  summarise(producao = sum(Prod_Modaloc, na.rm = TRUE), .groups = "drop") %>% 
  filter(Departamentos2 != "Centro") %>% # remover esse centro que apareceu do nada "Centro - CE"
  #left_join(docentes_por_depto) %>% 
  mutate(#producao_por_docente = producao,#/total_docentes,
         producao_padronizado = producao/sum(producao, na.rm = TRUE),
         rank_producao_padronizado = 
           dense_rank(desc(producao_padronizado))) %>% 
  rename("Departamento"=Departamentos2) 

# imprimir tabela 
producao02 %>% select(Centro, Departamento, producao, 
                      producao_padronizado, rank_producao_padronizado) %>% 
  arrange(rank_producao_padronizado) %>% 
  datatable(rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller'),
          options = list(pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('producao_padronizado',
              background = styleColorBar(range(producao02$producao_padronizado), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') 

Alocação de Recursos

\[ Aloc_j = \frac{(DP_j + QP_j + PP_j)}{3} * ORC \] Em que

  • \(Aloc_j\) é a alocação do orçamento para o departamento \(j\);
  • \(DP_j\) é o valor da variável Dimensão padronizada;
  • \(QP_j\) é o valor da variável Qualidade padronizada;
  • \(PP_j\) é o valor da variável Produção padronizada e
  • \(ORC\) é o valor do orçamento a ser distribuído.

Nesta simulação, foi considerado um orçamento de \(ORC = R\$ 4.000.000\).

A dimensão padronizada do departamento \(j\) é dada por:

\[ DP_j = \frac{(P_{esforco} * EDP_j + P_{esforcoPOS} * EDPPOS_j + P_{rap} * RAP_j + P_{rapPOS}*RAPPOS_j)}{(P_{esforco} + P_{esforcoPOS} + P_{rap} + P_{rapPOS})} \] Em que

  • \(P_{esforco}\) é o peso do esforço docente na graduação;
  • \(EDP_j\) é o Esforço Docente Padronizado na graduação do departamento \(j\);
  • \(P_{esforcoPOS}\) é o peso do esforço docente na pós-graduação;
  • \(EDPPOS_j\) é o Esforço Docente Padronizado na pós-graduação do departamento \(j\);
  • \(P_{rap}\) é o peso da Relação Aluno/Professor na graduação;
  • \(RAP_j\) é a Relação Aluno/Professor padronizado na graduação do departamento \(j\);
  • \(P_{rapPOS}\) é o peso da Relação Aluno/Professor na pós-graduação;
  • \(RAPPOS_j\) é a Relação Aluno/Professor padronizado na pós-graduação do departamento \(j\);

Nesta simulação, os pesos foram mantidos iguais a 1.

A qualidade padronizada do departamento \(j\) é dada por:

\[ QP_j = \frac{P_{IQCDP}*IQCDP_j + P_{ava\_grad}*IAVA\_grad_j + P_{ava\_POS}*IAVA\_POS_j + P_{TSG}*ITSG_j} {P_{IQCDP} + P_{ava\_grad} + P_{ava\_POS} + P_{TSG}} \]

em que

  • \(QP_j\) é a qualidade padronizada do departamento \(j\);
  • \(IQCDP_j\) é O Índice de Qualificação do Corpo Docente Padronizado;
  • \(P_{IQCDP}\) é o peso do Índice de Qualificação do Corpo Docente Padronizado;
  • \(IAVA\_grad_j\) é o Índice de Avaliação da Graduação - média do centro;
  • \(P_{ava\_grad}\) é o peso do Índice de Avaliação da Graduação - média do centro;
  • \(IAVA\_POS_j\) é o Índice de Avaliação da Pós-Graduação - média do centro;
  • \(P_{ava\_POS}\) é o peso do Índice de Avaliação da Pós-Graduação - média do centro;
  • \(ITSG_j\) é o Índice da Taxa de Sucesso na Graduação - média do centro;
  • \(P_{TSG}\) é o peso do Índice da Taxa de Sucesso na Graduação - média do centro;

A produção padronizada do departamento \(j\) é dada por:

\[ PP_j = \frac{P_{IPB}*IPB_j}{P_{IPB}} \]

em que

  • \(PP_j\) é a produção padronizada do departamento \(j\);
  • \(IPB_j\) é A produção bibliográfica padronizada;
  • \(P_{IPB}\) é o peso da produção bibliográfica padronizada;

OBS.:São consideradas produções bibliográficas os artigos, capítulos ou livros publicados e publicações em eventos.

# tabela final
peso_esforco = 1
peso_esforco_POS = 1
peso_rap = 1
peso_rap_POS = 1
peso_IQCD = 1
peso_producao = 1
peso_avaliacao = 1
peso_avaliacao_POS = 1
peso_TSG = 1
valor_orcamento = 4000000

esforco_docente %>% 
  left_join(esforco_docente_POS, by=c("Centro","Departamento")) %>% 
  left_join(relacao_aluno_professor) %>% 
  left_join(relacao_aluno_professor_POS) %>% 
  left_join(Qualidade, by=c("Centro","Departamento")) %>%
  left_join(producao02, by=c("Centro","Departamento")) %>% 
  left_join(particao_depart, by="Centro") %>%
  imputeTS::na_replace(0) %>% 
  mutate(
    dimensao_padronizado = 
      (peso_esforco * ESFORCO_DOCENTE_DEPTO_PADRONIZADO + 
         peso_esforco_POS * ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS + 
         peso_rap * rap_padronizado + 
         peso_rap_POS*rap_padronizado_POS)/
      (peso_esforco + peso_esforco_POS + peso_rap + peso_rap_POS),
    
    # o peso vai apenas no RAP
    dimensao_padronizado_PESO = 
      (peso_esforco * ESFORCO_DOCENTE_DEPTO_PADRONIZADO + 
         peso_esforco_POS * ESFORCO_DOCENTE_DEPTO_PADRONIZADO_POS + 
         peso_rap * rap_padronizado_PESO +
         peso_rap_POS * rap_padronizado_PESO_POS)/
      (peso_esforco + peso_esforco_POS + peso_rap + peso_rap_POS),
    
    qualidade_padronizado = (peso_IQCD*IQCD_padronizado +
                               peso_avaliacao*media_aval_grad_padronizado +
                               peso_avaliacao_POS*media_aval_POS_padronizado +
                               peso_TSG*TSG_media_padronizado)/
      (peso_IQCD + peso_avaliacao + peso_avaliacao_POS + peso_TSG),
    
    producao_padronizado = peso_producao*
      producao_padronizado/(peso_producao),
  
    alocacao = (dimensao_padronizado + qualidade_padronizado +
                  producao_padronizado)/3 * valor_orcamento,
    
    alocacao_PESO = (dimensao_padronizado_PESO + 
                             qualidade_padronizado +
                       producao_padronizado)/3 * valor_orcamento,
    
    alocacao_depto = alocacao * `COTA DEPART`,
    alocacao_centro = alocacao * `COTA CENTRO`,
    
    alocacao_depto_PESO = alocacao_PESO * `COTA DEPART`, 
    alocacao_centro_PESO = alocacao_PESO * `COTA CENTRO`,
    
    rank_alocacao_depto=dense_rank(desc(alocacao_depto)),
    rank_alocacao_depto_PESO=dense_rank(desc(alocacao_depto_PESO))
    
  ) %>% 
  relocate(c("COTA DEPART", "COTA CENTRO"), .after="alocacao_PESO") %>% 
  arrange(rank_alocacao_depto) -> tabela_final

# imprimir tabela 
datatable(tabela_final, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller', 'Buttons'),
          options = list(dom = 'Bfrtip',
                         extend = 'collection',
                         buttons = c('csv', 'excel'),
                         text = 'Download',
                         pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(which(sapply(.,is.numeric)), digits = 2) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow') %>% 
  formatStyle('alocacao_depto',
              background = styleColorBar(range(tabela_final$alocacao_depto), 'lightblue'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') %>% 
  formatStyle('alocacao_depto_PESO',
              background = styleColorBar(range(tabela_final$alocacao_depto_PESO), 'lightgreen'),
              backgroundSize = '98% 88%',
              backgroundRepeat = 'no-repeat',
              backgroundPosition = 'center') 

A distribuição dos recursos por Centro fica:

# alocacao por centro
tabela_final %>% group_by(Centro) %>% 
  summarize(alocacao_centro = sum(alocacao_centro),
            alocacao_centro_PESO = sum(alocacao_centro_PESO)) %>% 
  mutate(
    rank_alocacao_centro=dense_rank(desc(alocacao_centro)),
    rank_alocacao_centro_PESO=dense_rank(desc(alocacao_centro_PESO))
  ) %>% as.data.frame %>% 
  arrange(rank_alocacao_centro) -> distribuicao_centros


# imprimir tabela 
datatable(distribuicao_centros, rownames = FALSE, 
          extensions = c("FixedColumns",'FixedHeader','Scroller', 'Buttons'),
          options = list(dom = 'Bfrtip',
                         extend = 'collection',
                         buttons = c('csv', 'excel'),
                         text = 'Download',
                         pageLength = 25, 
                         scrollX=T,
                         fixedHeader = TRUE,
                         columnDefs = list(list(className = 'dt-center', targets = "_all")),
                         fixedColumns = list(leftColumns = 2))) %>%
  formatRound(which(sapply(.,is.numeric)), digits = 2) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') #%>% 
  # formatStyle('alocacao_centro',
  #             background = styleColorBar(range(distribuicao_centros$alocacao_centro), 'lightblue'),
  #             backgroundSize = '98% 88%',
  #             backgroundRepeat = 'no-repeat',
  #             backgroundPosition = 'center') %>% 
  # formatStyle('alocacao_centro_PESO',
  #             background = styleColorBar(range(distribuicao_centros$alocacao_centro_PESO), 'lightgreen'),
  #             backgroundSize = '98% 88%',
  #             backgroundRepeat = 'no-repeat',
  #             backgroundPosition = 'center') 

A distribuição dos recursos por Departamento fica:

tabela_final %>% select(Centro, Departamento, alocacao_depto, 
                        alocacao_depto_PESO) %>% 
  mutate(
    rank_alocacao_depto=dense_rank(desc(alocacao_depto)),
    rank_alocacao_depto_PESO=dense_rank(desc(alocacao_depto_PESO))
  ) %>% filter(alocacao_depto > 0) %>% 
  # imprimir tabela 
  datatable(tabela_final, rownames = FALSE, 
            extensions = c("FixedColumns",'FixedHeader','Scroller', 'Buttons'),
            options = list(dom = 'Bfrtip',
                           extend = 'collection',
                           buttons = c('csv', 'excel'),
                           text = 'Download',
                           pageLength = 25, 
                           scrollX=T,
                           fixedHeader = TRUE,
                           columnDefs = list(list(className = 'dt-center', targets = "_all")),
                           fixedColumns = list(leftColumns = 2))) %>%
  formatRound(which(sapply(.,is.numeric)), digits = 2) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow')  

Comparação

Para verificar se a alteração da alocação ocorrida com a introdução dos pesos por departamento foi estatisticamente significativa, utilizamos o teste de Wilcoxon para amostras pareadas.

O resultado mostra que há diferença significativa, ou seja, a introdução dos pesos altera a alocação de recursos.

# Ha diferenca significativa entre a alocacao e a alocacao com peso para
# os alunos no departamento?
# Realizando o teste de Wilcoxon
resultado <- wilcox.test(tabela_final$alocacao_depto, 
                         tabela_final$rank_alocacao_depto_PESO, paired = TRUE)

# Imprimindo o resultado
print(resultado)
## 
##  Wilcoxon signed rank test with continuity correction
## 
## data:  tabela_final$alocacao_depto and tabela_final$rank_alocacao_depto_PESO
## V = 2769, p-value = 1.008e-13
## alternative hypothesis: true location shift is not equal to 0
# Interpretando o valor-p
if (resultado$p.value < 0.05) {
  print("Rejeita-se a hipótese nula: há diferença significativa entre as amostras.")
} else {
  print("Não se rejeita a hipótese nula: não há diferença significativa entre as amostras.")
}
## [1] "Rejeita-se a hipótese nula: há diferença significativa entre as amostras."

E para os Centros, a adoção dos pesos não implica em diferença estatisticamente significativa na distribuição dos recursos:

# Ha diferenca significativa entre a alocacao e a alocacao com peso para
# os alunos no centro?
# Realizando o teste de Wilcoxon
resultado <- wilcox.test(distribuicao_centros$alocacao_centro, 
                         distribuicao_centros$alocacao_centro_PESO, paired = TRUE)

# Imprimindo o resultado
print(resultado)
## 
##  Wilcoxon signed rank exact test
## 
## data:  distribuicao_centros$alocacao_centro and distribuicao_centros$alocacao_centro_PESO
## V = 49, p-value = 0.8394
## alternative hypothesis: true location shift is not equal to 0
# Interpretando o valor-p
if (resultado$p.value < 0.05) {
  print("Rejeita-se a hipótese nula: há diferença significativa entre as amostras.")
} else {
  print("Não se rejeita a hipótese nula: não há diferença significativa entre as amostras.")
}
## [1] "Não se rejeita a hipótese nula: não há diferença significativa entre as amostras."

Modaloc Modelo antigo

Na tabela abaixo vemos as mudanças na alocação de recursos aos departamentos.

modaloc_priscila %>% 
  filter(!Centro %in% c("CCM", "CCJ", "CIn")) %>% 
  select(Centro, "Departamento" = Departamentos2, PESO_PRI = PESO, 
                            #Alocação_anterior, 
                            "Alocacao_PRI" = AlocaçãoDepto) %>% 
left_join(
tabela_final %>% select(Centro, Departamento, "alocacao_NOVO"=alocacao_depto,
                        "PESO_NOVO" = PESO,
                        "alocacao_peso_NOVO" = alocacao_depto_PESO), 
by = c("Centro", 'Departamento')) %>% 
  mutate(Diferenca = alocacao_NOVO - Alocacao_PRI,
         Diferenca_PESO = alocacao_peso_NOVO - Alocacao_PRI) -> 
  tabela_comparacao_deptos

# imprimir tabela 
tabela_comparacao_deptos %>% 
  datatable(rownames = FALSE, 
            extensions = c("FixedColumns",'FixedHeader','Scroller', 'Buttons'),
            options = list(dom = 'Bfrtip',
                           extend = 'collection',
                           buttons = c('csv', 'excel'),
                           text = 'Download',
                           pageLength = 25, 
                           scrollX=T,
                           fixedHeader = TRUE,
                           columnDefs = list(list(className = 'dt-center', targets = "_all")),
                           fixedColumns = list(leftColumns = 2))) %>%
  formatRound(which(sapply(.,is.numeric)), digits = 2) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow') %>% 
  formatStyle('Departamento', backgroundColor = 'lightyellow')  
# grafico
tabela_comparacao_deptos %>% e_charts(Departamento) %>%
  e_bar(Diferenca) %>%
  e_tooltip() %>%
  e_axis(axisLabel = list(interval = 0, rotate=45)) %>%
  e_grid(bottom = 300) 

Na tabela abaixo vemos as mudanças na alocação de recursos aos Centros.

distribuicao_centros %>% 
  select(Centro, alocacao_centro, alocacao_centro_PESO) %>% 
  left_join(modaloc_priscila %>% 
              group_by(Centro) %>% 
              summarise(Alocacao_centro_PRI = sum(AlocaçãoCentro)), by="Centro") %>% 
  mutate(Diferenca_PESO = alocacao_centro_PESO - Alocacao_centro_PRI,
    Diferenca = alocacao_centro - Alocacao_centro_PRI) %>% 
  # imprimir tabela 
  datatable(rownames = FALSE, 
            extensions = c("FixedColumns",'FixedHeader','Scroller', 'Buttons'),
            options = list(dom = 'Bfrtip',
                           extend = 'collection',
                           buttons = c('csv', 'excel'),
                           text = 'Download',
                           pageLength = 25, 
                           scrollX=T,
                           fixedHeader = TRUE,
                           columnDefs = list(list(className = 'dt-center', targets = "_all")),
                           fixedColumns = list(leftColumns = 2))) %>%
  formatRound(which(sapply(.,is.numeric)), digits = 2) %>% 
  formatStyle('Centro', backgroundColor = 'lightyellow')

Diferença entre os modelos

No modelo antigo, o peso do departamento era aplicado ao esforço total e padronizado, dando origem ao índice final, que corresponde à fração do orçamento alocada àquele departamento. Desta forma, o peso do departamento é aplicado a TODAS as variáveis, incluindo a pesquisa.

\[ ET_i = \frac{ICHDM_i + IAHS_i + ITRABPUB_i}{3} \\ \]

\[ ET\_PESO_i = ET_i \times PESO_i \\ \]

\[ IF = \frac{ET\_PESO}{\sum{ET\_PESO}} \]

Já no modelo aqui proposto, temos duas opções: ou o peso não é aplicado, ou é aplicado apenas na variável Relação Matrícula/Professor. Então, os departamentos são tratados de forma semelhante, por exemplo, com a produção acadêmica recebendo o mesmo peso, independentemente do departamento. Isso resultou numa ampla modificação na alocação de recursos.