Lab 01 - FPCC 2

Com base no arquivo de dados (no diretório data) responda as questões abaixo, gerando um relatório final com as respostas. Cada resposta deve gerar tabelas e/ou gráficos para apresentar os resultados obtidos, além de uma justificativa para a escolha de métricas, estatísticas e visualizações. Vocês podem se basear no arquivo R Markdown gerado em sala (no diretório reports). O relatório final deve ser adicionado ao repositório do seu lab (por exemplo, um arquivo PDF)..

library(readr)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ purrr     1.0.2
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
dff <- read_csv("Data/cursos-prouni.csv")
## Rows: 41447 Columns: 20
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr  (9): grau, turno, curso_busca, cidade_busca, uf_busca, cidade_filtro, u...
## dbl (11): mensalidade, bolsa_integral_cotas, bolsa_integral_ampla, bolsa_par...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
adiciona_coluna_regiao <- function(dff) {
  dpr <- dff %>%
  mutate(regiao = case_when(
    uf_busca %in% c("AL","PB", "PE", "PI", "MA", "RN", "SE", "CE", "BA") ~ "NE",
    uf_busca %in% c("SP","RJ", "MG", "ES") ~ "SE",
    uf_busca %in% c("AM","AP", "PA", "RR", "RO", "TO", "AC") ~ "N",
    uf_busca %in% c("DF","GO", "MS", "MT") ~ "CO",
    uf_busca %in% c("RS","PR", "SC") ~ "S"
  ))
  return(dpr)
}

agrupa_resultados_por_regiao <- function(dff) {
  dpr <- dff %>% 
  group_by(regiao) %>% 
  summarise(mens_media = mean(mensalidade),
            mens_median = median(mensalidade))
  
  return(dpr)
}

filtra_resultados_por_regiao <- function(dff, conjunto) {
  dpr <- filter(dff, regiao %in% conjunto)
  return(dpr)
}

monta_grafico_por_regiao <- function(dff) {
  dpr <- ggplot(dff, aes(reorder(regiao, mens_media), mens_media, fill=regiao)) + 
  geom_bar(stat = 'identity') + 
  geom_point(aes(y=mens_median)) + 
  theme_bw() + 
  theme(legend.position = "none") + 
  xlab('Região') + ylab('Mensalidade média') +
  labs(title = "Mensalidade média e mediana por região")
  
  return(dpr)
}

testar_diferenca_medias <- function(amostra1, amostra2, nivel_significancia = 0.05) {
  # Realiza o teste t de Student
  resultado_teste <- t.test(amostra1, amostra2)
  
  # Extrai o p-valor do resultado do teste
  p_valor <- resultado_teste$p.value
  
  # Compara o p-valor com o nível de significância
  if (p_valor < nivel_significancia) {
    mensagem <- "Diferença de médias é estatisticamente significativa"
  } else {
    mensagem <- "Diferença de médias não é estatisticamente significativa"
  }
  
  # Retorna o resultado do teste
  return(list(
    mensagem = mensagem,
    p_valor = p_valor,
    estatistica_t = resultado_teste$statistic
  ))
}

testar_diferenca_medianas <- function(amostra1, amostra2, nivel_significancia = 0.05) {
  # Realiza o teste U de Mann-Whitney
  resultado_teste <- wilcox.test(amostra1, amostra2)
  
  # Extrai o p-valor do resultado do teste
  p_valor <- resultado_teste$p.value
  
  # Compara o p-valor com o nível de significância
  if (p_valor < nivel_significancia) {
    mensagem <- "Diferença de medianas é estatisticamente significativa"
  } else {
    mensagem <- "Diferença de medianas não é estatisticamente significativa"
  }
  
  # Retorna o resultado do teste
  return(list(
    mensagem = mensagem,
    p_valor = p_valor,
    estatistica_U = resultado_teste$statistic
  ))
}

agrupa_total_de_bolsas_por_resultado <- function(dff) {
  dpr <- dff$bolsa_integral_cotas[is.na(dff$bolsa_integral_cotas)] <- 0
  dpr <- dff$bolsa_parcial_cotas[is.na(dff$bolsa_parcial_cotas)] <- 0
  dpr <- dff$bolsa_integral_ampla[is.na(dff$bolsa_integral_ampla)] <- 0
  dpr <- dff$bolsa_parcial_ampla[is.na(dff$bolsa_parcial_ampla)] <- 0
  dpr <- dff %>%
    mutate(total_bolsas = bolsa_integral_cotas + bolsa_parcial_cotas + bolsa_integral_ampla + bolsa_parcial_ampla)
  
  return(dpr)
}

agrupa_curso_por_mensalidade_e_total_bolsas <- function(dff) {
  dpr <- dff %>% 
  group_by(curso_busca) %>% 
  summarise(c_total_bolsas = sum(total_bolsas),
            c_mensalidade = sum(mensalidade),
            m_mensalidade = mean(mensalidade),
            m_total_bolsas = mean(total_bolsas),
            mensalidade_per_total_bolsas = sum(mensalidade)/sum(total_bolsas))
  
  return(dpr)
}

ordena_resultados_e_retorna_10 <- function(dff) {
  dpr <- arrange(dff, desc(mensalidade_per_total_bolsas))
  dpr <- dpr[0:10,]
  
  return(dpr)
}

monta_grafico_mensalidade_por_total_de_bolsas <- function(dff) {
  dpr <- ggplot(dff, aes(reorder(curso_busca, mensalidade_per_total_bolsas), mensalidade_per_total_bolsas, fill=curso_busca)) + 
  geom_bar(stat = 'identity') + 
  geom_point(aes(y=m_mensalidade)) + 
  theme_bw() + 
  theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1)) + 
  xlab('Curso') + ylab('Mensalidade total / bolsas ofertadas') +
  labs(title = "Relação entre mensalidade total e total de bolsas ofertadas por curso")
  
  return(dpr)
}

verificar_correlacao_entre_2_colunas <- function(amostra, coluna1, coluna2) {
  # Verifica se as colunas existem na amostra
  if(!(coluna1 %in% names(amostra)) || !(coluna2 %in% names(amostra))) {
    stop("As colunas especificadas não existem na amostra.")
  }
  
  # Calcula a correlação entre as duas colunas
  correlacao <- cor(amostra[[coluna1]], amostra[[coluna2]])
  
  # Retorna se há correlação significativa ou não
  if(abs(correlacao) >= 0.7) {
    mensagem <- "Há uma correlação forte entre as duas colunas."
  }
  else if(abs(correlacao) >= 0.4) {
    mensagem <- "Há uma correlação moderada entre as duas colunas."
  }
  else {
    mensagem <- "Não há uma correlação significativa entre as duas colunas."
  }
  
  return(list(
    mensagem = mensagem,
    correlacao = round(abs(correlacao),2)
  ))
}

filtra_curso_por_grau <- function(dff, grau_escolhido) {
  dpr <- filter(dff, grau %in% grau_escolhido)
  return(dpr)
}
  
filtra_curso_por_uf <- function(dff, uf_escolhida) {
  dpr <- filter(dff, uf_busca %in% uf_escolhida)
  return(dpr)
}
  
agrupa_curso_por_bolsas <- function(dff) {
  dpr <- dff %>% 
  group_by(curso_busca) %>% 
  summarise(c_total_bolsas = sum(total_bolsas),
            c_bolsa_integral_cotas = sum(bolsa_integral_cotas),
            c_bolsa_parcial_cotas = sum(bolsa_parcial_cotas),
            c_bolsa_integral_ampla = sum(bolsa_integral_ampla),
            c_bolsa_parcial_ampla = sum(bolsa_parcial_ampla))

  dpr <- arrange(dpr,desc(c_total_bolsas))
  
  return(dpr)
}

filtra_curso_por_nomes <- function(dff, nomes) {
  dpr <- filter(dff, curso_busca %in% nomes)
  
  return(dpr)
}

agrupa_dados_por_curso_e_modalidade <- function(dff) {
  dpr <- dff %>% 
    group_by(curso_busca, turno) %>% 
    summarise(c_total_bolsas = sum(total_bolsas))
  
  return(dpr)
}

monta_grafico_agrupado_por_bolsa_e_modalidade <- function(dff) {
  dpr <- transform(dff, percentual = c_total_bolsas / ave(c_total_bolsas, curso_busca, FUN = sum) * 100)

  # Criando o gráfico de barras empilhadas percentuais
  grafico <- ggplot(dpr, aes(x = curso_busca, y = percentual, fill = turno, label = paste0(round(percentual), "%"))) +
    geom_bar(stat = "identity", position = "fill") +  # Barras empilhadas e escalonadas para 100%
    labs(x = "Curso", y = "Porcentagem de bolsas por modalidade") +
    scale_y_continuous(labels = scales::percent) +  # Define o eixo y para exibir porcentagens
    theme_minimal() +
    theme(legend.position = "right") +
    geom_text(position = position_fill(vjust = 0.5)) +
    labs(fill = "Modalidade:") +
    labs(title = "Percentual de bolsas ofertadas por modalidade de curso")
  
  return(grafico)
}

monta_grafico_por_bolsas_empilhadas <- function(dff) {

  # Transformando os dados para um formato adequado para o ggplot2
  dff <- dff %>%
    mutate(total = c_bolsa_integral_cotas + c_bolsa_parcial_cotas + c_bolsa_integral_ampla + c_bolsa_parcial_ampla)
  
  dff <- dff %>%
    arrange(total)
  
  # Reordenando o fator no eixo x de acordo com a ordem das somas totais
  dff$curso_busca <- factor(dff$curso_busca, levels = dff$curso_busca)
  
  dff <- dff %>%
    pivot_longer(cols = c(c_bolsa_integral_cotas, c_bolsa_parcial_cotas, c_bolsa_integral_ampla, c_bolsa_parcial_ampla), names_to = "Categoria", values_to = "Valor")
  
  dff <- dff %>%
    arrange(Categoria, Valor)

  # Criando o gráfico de barras empilhadas
  grafico <- ggplot(dff, aes(x = curso_busca, y = Valor, fill = Categoria)) +
    geom_bar(stat = "identity") +
    labs(x = "Curso", y = "Quantidade de bolsas", fill = "") +
    theme_minimal() +
    theme(legend.position = "bottom", axis.text.x = element_text(angle = 45, hjust = 1))
    labs(title = "Quantidade de bolsas ofertadas por curso tecnológico") 
    
  return(grafico)
}

Questão 01

Qual a diferença entre as mensalidades médias e medianas dos cursos de Ciência da Computação do Nordeste e Sudeste? Na sua opnião, essa diferença é estatisticamente significativa? Justifique.

Valores Médios e Medianos das regiões Nordete e Sudeste (mediana pontuada):

dados_com_regiao <- adiciona_coluna_regiao(dff)
dados_filtrados_por_curso <- filtra_curso_por_nomes(dados_com_regiao, c("Ciência da Computação"))
dados_agrupados_por_regiao <- agrupa_resultados_por_regiao(dados_filtrados_por_curso)
dados_filtrados_por_regiao <- filtra_resultados_por_regiao(dados_agrupados_por_regiao, c("SE", "NE"))

print(monta_grafico_por_regiao(dados_filtrados_por_regiao))

Para estabelecer se há ou não significância estatística entre as médias obtidas, podemos utilizar o teste t de Student com nível de significância = 0,05:

amostra_sudeste <- filter(dados_filtrados_por_curso, regiao %in% c("SE"))
amostra_nordeste <- filter(dados_filtrados_por_curso, regiao %in% c("NE"))

resultado_media <- testar_diferenca_medias(amostra_sudeste$mensalidade, amostra_nordeste$mensalidade)

print(resultado_media$mensagem)
## [1] "Diferença de médias é estatisticamente significativa"
print(paste("P-valor:", resultado_media$p_valor))
## [1] "P-valor: 0.00288446946878206"
print(paste("Estatística t:", resultado_media$estatistica_t))
## [1] "Estatística t: 3.06312127095578"

Após o teste, constata-se que a diferença entre as médias é significativamente estatística.

Para estabelecer se há ou não significância estatística entre as médias obtidas, podemos utilizar o teste Wilcoxon-Mann-Whitney com nível de significância = 0,05:

amostra_sudeste <- filter(dados_filtrados_por_curso, regiao %in% c("SE"))
amostra_nordeste <- filter(dados_filtrados_por_curso, regiao %in% c("NE"))

resultado_mediana <- testar_diferenca_medianas(amostra_sudeste$mensalidade, amostra_nordeste$mensalidade)

print(resultado_mediana$mensagem)
## [1] "Diferença de medianas é estatisticamente significativa"
print(paste("P-valor:", resultado_mediana$p_valor))
## [1] "P-valor: 0.0285398531277037"
print(paste("Estatística U:", resultado_mediana$estatistica_U))
## [1] "Estatística U: 2202.5"

Após o teste, constata-se que a diferença entre as medianas é significativamente estatística.

Questão 02

Quais são os top 10 cursos com maior valor de mensalidade pelo total de bolsas (diferentes tipos)? Existe uma relação entre o valor total de mensalidade e o total de bolsas por curso? Justifique.

Valores das 10 maiores relações entre mensalidades totais pelo total de bolsas ofertadas por curso (média pontuada):

dados_com_bolsas_somadas <- agrupa_total_de_bolsas_por_resultado(dff)
dados_agrupados_por_mensalidade_e_bolsas <- agrupa_curso_por_mensalidade_e_total_bolsas(dados_com_bolsas_somadas)
dados_ordenados_e_limitados <- ordena_resultados_e_retorna_10(dados_agrupados_por_mensalidade_e_bolsas)

print(monta_grafico_mensalidade_por_total_de_bolsas(dados_ordenados_e_limitados))

Para analisar se existe relação entre o valor total de mensalidade e o total de bolsas por curso, podemos usar uma função de correlação e interpretar seu resultado:

resultado <- verificar_correlacao_entre_2_colunas(dados_agrupados_por_mensalidade_e_bolsas, "c_total_bolsas", "c_mensalidade")
print(paste("Correlação:", resultado$correlacao))
## [1] "Correlação: 0.93"
print(resultado$mensagem)
## [1] "Há uma correlação forte entre as duas colunas."

Após o resultado da correlação, é possível inferir que existe uma relação significativa entre o valor total de mensalidade e o total de bolsas ofertadas por curso.

Questão 03

Quais são os cursos tecnológicos da Paraíba que oferecem mais bolsas de estudo e quantas bolsas de cada tipo estes cursos oferecem?

Os cursos tecnológicos da Paraíba que mais oferecem mais bolsas e quantas bolsas de cada tipo cada curso oferece pode ser visualizada na tabela a seguir:

dados_com_total_de_bolsas <- agrupa_total_de_bolsas_por_resultado(dff)
dados_filtrados_por_grau <- filtra_curso_por_grau(dados_com_total_de_bolsas, c("Tecnológico"))
dados_filtrados_por_estado <- filtra_curso_por_uf(dados_filtrados_por_grau, c("PB"))
dados_agrupados_por_bolsa <- agrupa_curso_por_bolsas(dados_filtrados_por_estado)

print(dados_agrupados_por_bolsa)
## # A tibble: 34 × 6
##    curso_busca       c_total_bolsas c_bolsa_integral_cotas c_bolsa_parcial_cotas
##    <chr>                      <dbl>                  <dbl>                 <dbl>
##  1 Gestão de Recurs…            124                     31                     3
##  2 Segurança no Tra…            110                     11                     1
##  3 Redes de Computa…            106                     16                     0
##  4 Gestão da Tecnol…             99                     12                     1
##  5 Negócios Imobili…             95                      6                     0
##  6 Logística                     80                      9                     1
##  7 Design de Interi…             53                     13                     0
##  8 Radiologia                    53                     12                     1
##  9 Gestão Comercial              27                     14                     5
## 10 Marketing                     27                     15                     4
## # ℹ 24 more rows
## # ℹ 2 more variables: c_bolsa_integral_ampla <dbl>, c_bolsa_parcial_ampla <dbl>
print(monta_grafico_por_bolsas_empilhadas(dados_agrupados_por_bolsa))

Questão 04

Considerando os cursos de Ciência da Computação, Engenharia da Computação e Sistemas de Informação, qual o percentual de bolsas ofertadas para cada modalidade (a distância, integral, noturno, etc.) por cada um dos cursos? Existe uma modalidade que é predominante?

Para os cursos Ciência da Computação, Engenharia da Computação e Sistemas de Informação é possível visualizar a distribuição de bolsas por modalidade através do gráfico a seguir:

dados_com_total_de_bolsas <- agrupa_total_de_bolsas_por_resultado(dff)
dados_filtrados_por_nome <- filtra_curso_por_nomes(dados_com_total_de_bolsas, c("Ciência da Computação", "Engenharia da Computação", "Sistemas de Informação"))
dados_agrupados_por_modalidade <- agrupa_dados_por_curso_e_modalidade(dados_filtrados_por_nome)
## `summarise()` has grouped output by 'curso_busca'. You can override using the
## `.groups` argument.
print(monta_grafico_agrupado_por_bolsa_e_modalidade(dados_agrupados_por_modalidade))

Pelos dados apresentados, há uma maior concentração de bolsa ofertadas na modalidade Norturno.