Desafio 11

library(reticulate)#abrindo o pacote reticulate
virtualenv_create("env_me315", python = "C:/Program Files/Python312/python.exe")#criando um ambiente virtual pra usar python
virtualenv: env_me315
use_virtualenv("env_me315", required = TRUE) #manda usar o ambiente virtual criado
#!pip install polars
#!pip install fastexcel
#importando o polars
import polars as pl

##1

# 1️⃣ Ler CSV rapidamente sem cabeçalho
df = pl.read_csv("renda_adulta.csv.gz", has_header = False, null_values="?")
# 2️⃣ Definir os nomes das colunas
colunas = [
    "age", "workclass", "fnlwgt", "education", "education-num",
    "marital-status", "occupation", "relationship", "race", "sex",
    "capital-gain", "capital-loss", "hours-per-week", "native-country",
    "income"
]
#definindo as colunas
df.columns = colunas
# 3️⃣ Converter tipos das colunas
tipos = {
    "age": pl.Int64,
    "workclass": pl.Categorical,
    "fnlwgt": pl.Int64,
    "education": pl.Categorical,
    "education-num": pl.Int64,
    "marital-status": pl.Categorical,
    "occupation": pl.Categorical,
    "relationship": pl.Categorical,
    "race": pl.Categorical,
    "sex": pl.Categorical,
    "capital-gain": pl.Int64,
    "capital-loss": pl.Int64,
    "hours-per-week": pl.Int64,
    "native-country": pl.Categorical,
    "income": pl.Categorical
}
df = df.with_columns([df[col].cast(tipo).alias(col) for col, tipo in tipos.items()])  # Converte cada coluna para o tipo definido em 'tipos' e mantém os nomes
print(df.head()) #mostra o inicio do df
shape: (5, 15)
┌─────┬──────────────┬────────┬───────────┬───┬──────────────┬──────────────┬─────────────┬────────┐
│ age ┆ workclass    ┆ fnlwgt ┆ education ┆ … ┆ capital-loss ┆ hours-per-we ┆ native-coun ┆ income │
│ --- ┆ ---          ┆ ---    ┆ ---       ┆   ┆ ---          ┆ ek           ┆ try         ┆ ---    │
│ i64 ┆ cat          ┆ i64    ┆ cat       ┆   ┆ i64          ┆ ---          ┆ ---         ┆ cat    │
│     ┆              ┆        ┆           ┆   ┆              ┆ i64          ┆ cat         ┆        │
╞═════╪══════════════╪════════╪═══════════╪═══╪══════════════╪══════════════╪═════════════╪════════╡
│ 39  ┆ State-gov    ┆ 77516  ┆ Bachelors ┆ … ┆ 0            ┆ 40           ┆ United-Stat ┆ <=50K  │
│     ┆              ┆        ┆           ┆   ┆              ┆              ┆ es          ┆        │
│ 50  ┆ Self-emp-not ┆ 83311  ┆ Bachelors ┆ … ┆ 0            ┆ 13           ┆ United-Stat ┆ <=50K  │
│     ┆ -inc         ┆        ┆           ┆   ┆              ┆              ┆ es          ┆        │
│ 38  ┆ Private      ┆ 215646 ┆ HS-grad   ┆ … ┆ 0            ┆ 40           ┆ United-Stat ┆ <=50K  │
│     ┆              ┆        ┆           ┆   ┆              ┆              ┆ es          ┆        │
│ 53  ┆ Private      ┆ 234721 ┆ 11th      ┆ … ┆ 0            ┆ 40           ┆ United-Stat ┆ <=50K  │
│     ┆              ┆        ┆           ┆   ┆              ┆              ┆ es          ┆        │
│ 28  ┆ Private      ┆ 338409 ┆ Bachelors ┆ … ┆ 0            ┆ 40           ┆ Cuba        ┆ <=50K  │
└─────┴──────────────┴────────┴───────────┴───┴──────────────┴──────────────┴─────────────┴────────┘

##2

# Mostrar os tipos de cada coluna
for col, dtype in zip(df.columns, df.dtypes):
    print(f"{col}: {dtype}")
age: Int64
workclass: Categorical
fnlwgt: Int64
education: Categorical
education-num: Int64
marital-status: Categorical
occupation: Categorical
relationship: Categorical
race: Categorical
sex: Categorical
capital-gain: Int64
capital-loss: Int64
hours-per-week: Int64
native-country: Categorical
income: Categorical

##3

# Dimensões do DataFrame
linhas, colunas = df.shape #tamanho do df
print(f"Número de linhas: {linhas}")
Número de linhas: 32561
print(f"Número de colunas: {colunas}")
Número de colunas: 15
print(f"Logo a dimentao é {linhas} x {colunas}")
Logo a dimentao é 32561 x 15

##4

# Contagem de pessoas por faixa de renda
acima_50k = df.filter(df["income"] == ">50K").height
abaixo_50k = df.filter(df["income"] == "<=50K").height

print(f"Pessoas que ganham acima de $50.000: {acima_50k}")
Pessoas que ganham acima de $50.000: 7841
print(f"Pessoas que ganham abaixo ou igual a $50.000: {abaixo_50k}")
Pessoas que ganham abaixo ou igual a $50.000: 24720

##5

import polars as pl

# Renomear as colunas wide para 'gain' e 'loss' para simplificar o melt
df_renomeado = df.rename({
    "capital-gain": "gain",
    "capital-loss": "loss"
})

# Transformar as colunas 'gain' e 'loss' de formato wide para longo
renda_longo = df_renomeado.unpivot(
    index=[col for col in df_renomeado.columns if col not in ["gain", "loss"]],  # mantém todas as outras colunas como identificadores
    on=["gain", "loss"],  # colunas que serão convertidas em formato longo
    variable_name="tipo",  # nome da coluna que indicará o tipo ('gain' ou 'loss')
    value_name="Valor"     # nome da coluna que armazenará os valores
)

# Exibir as primeiras linhas do DataFrame longo para verificar o resultado
print(renda_longo.head())
shape: (5, 15)
┌─────┬──────────────────┬────────┬───────────┬───┬────────────────┬────────┬──────┬───────┐
│ age ┆ workclass        ┆ fnlwgt ┆ education ┆ … ┆ native-country ┆ income ┆ tipo ┆ Valor │
│ --- ┆ ---              ┆ ---    ┆ ---       ┆   ┆ ---            ┆ ---    ┆ ---  ┆ ---   │
│ i64 ┆ cat              ┆ i64    ┆ cat       ┆   ┆ cat            ┆ cat    ┆ str  ┆ i64   │
╞═════╪══════════════════╪════════╪═══════════╪═══╪════════════════╪════════╪══════╪═══════╡
│ 39  ┆ State-gov        ┆ 77516  ┆ Bachelors ┆ … ┆ United-States  ┆ <=50K  ┆ gain ┆ 2174  │
│ 50  ┆ Self-emp-not-inc ┆ 83311  ┆ Bachelors ┆ … ┆ United-States  ┆ <=50K  ┆ gain ┆ 0     │
│ 38  ┆ Private          ┆ 215646 ┆ HS-grad   ┆ … ┆ United-States  ┆ <=50K  ┆ gain ┆ 0     │
│ 53  ┆ Private          ┆ 234721 ┆ 11th      ┆ … ┆ United-States  ┆ <=50K  ┆ gain ┆ 0     │
│ 28  ┆ Private          ┆ 338409 ┆ Bachelors ┆ … ┆ Cuba           ┆ <=50K  ┆ gain ┆ 0     │
└─────┴──────────────────┴────────┴───────────┴───┴────────────────┴────────┴──────┴───────┘

##6

# Calcula a média de horas trabalhadas por semana agrupando pelo nível salarial ('income')
media_horas = df.group_by("income").agg(
    pl.col("hours-per-week").mean().alias("media_horas")  # calcula a média da coluna 'hours-per-week' e renomeia para 'media_horas'
)

# Exibe o resultado com a média de horas por classe salarial
print(media_horas)
shape: (2, 2)
┌────────┬─────────────┐
│ income ┆ media_horas │
│ ---    ┆ ---         │
│ cat    ┆ f64         │
╞════════╪═════════════╡
│ >50K   ┆ 45.473026   │
│ <=50K  ┆ 38.84021    │
└────────┴─────────────┘

##7

# Conta quantas pessoas existem em cada profissão
contagem_profissao = (
    df.group_by("occupation")  # agrupa o DataFrame pela coluna 'occupation'
      .agg(
          pl.len().alias("num_pessoas")  # conta o número de linhas em cada grupo e renomeia para 'num_pessoas'
      )
      .sort("num_pessoas", descending=True)  # ordena as profissões do maior para o menor número de pessoas
)

# Exibe a contagem de pessoas por profissão
print(contagem_profissao)
shape: (15, 2)
┌─────────────────┬─────────────┐
│ occupation      ┆ num_pessoas │
│ ---             ┆ ---         │
│ cat             ┆ u32         │
╞═════════════════╪═════════════╡
│ Prof-specialty  ┆ 4140        │
│ Craft-repair    ┆ 4099        │
│ Exec-managerial ┆ 4066        │
│ Adm-clerical    ┆ 3770        │
│ Sales           ┆ 3650        │
│ …               ┆ …           │
│ Farming-fishing ┆ 994         │
│ Tech-support    ┆ 928         │
│ Protective-serv ┆ 649         │
│ Priv-house-serv ┆ 149         │
│ Armed-Forces    ┆ 9           │
└─────────────────┴─────────────┘

##8

#!pip install matplotlib
import matplotlib
matplotlib.use("Agg")  # Define o backend 'Agg', que não depende do Tkinter, útil para gerar gráficos em RMarkdown/HTML

import matplotlib.pyplot as plt  # Importa a interface pyplot do Matplotlib para criar gráficos
# Calcula a média de horas trabalhadas por semana agrupando pelo nível salarial ('income')
media_horas = df.group_by("income").agg(
    pl.col("hours-per-week").mean().alias("media_horas")  # calcula a média da coluna 'hours-per-week' e renomeia para 'media_horas'
)

# Extrai os nomes das classes salariais e os valores médios diretamente do Polars para plotagem
classes = media_horas["income"].to_list()  # lista com as categorias de 'income'
valores = media_horas["media_horas"].to_list()  # lista com as médias correspondentes

# Criar gráfico de barras usando Matplotlib
plt.figure(figsize=(8,5))  # define o tamanho da figura
plt.bar(classes, valores, color=['skyblue', 'salmon'])  # cria barras com cores diferentes para cada classe
plt.title("Média de Horas Trabalhadas por Semana por Classe Salarial")  # título do gráfico
plt.xlabel("Classe Salarial")  # rótulo do eixo x
plt.ylabel("Horas Semanais Médias")  # rótulo do eixo y
plt.ylim(0, max(valores) + 5)  # ajusta o limite superior do eixo y para melhor visualização
(0.0, 50.473026399693914)
plt.show()  # exibe o gráfico

##Desafio

# Contagem total de pessoas por gênero
total_por_genero = df.group_by("sex").agg(
    pl.len().alias("total")  # conta o número de linhas por gênero e renomeia para 'total'
)

# Contagem de pessoas com income >50K por gênero
acima_50k_por_genero = df.filter(df["income"] == ">50K").group_by("sex").agg(
    pl.len().alias("acima_50k")  # conta o número de pessoas ganhando acima de 50K por gênero
)

# Juntar os resultados e calcular a porcentagem de pessoas com income >50K
distribuicao_genero = total_por_genero.join(acima_50k_por_genero, on="sex", how="left").with_columns(
    (pl.col("acima_50k") / pl.col("total") * 100).alias("perc_acima_50k")  # calcula a proporção em porcentagem
)

# Exibe a tabela com total, acima de 50K e porcentagem por gênero
print(distribuicao_genero)
shape: (2, 4)
┌────────┬───────┬───────────┬────────────────┐
│ sex    ┆ total ┆ acima_50k ┆ perc_acima_50k │
│ ---    ┆ ---   ┆ ---       ┆ ---            │
│ cat    ┆ u32   ┆ u32       ┆ f64            │
╞════════╪═══════╪═══════════╪════════════════╡
│ Female ┆ 10771 ┆ 1179      ┆ 10.946059      │
│ Male   ┆ 21790 ┆ 6662      ┆ 30.573658      │
└────────┴───────┴───────────┴────────────────┘
# Comentário final interpretativo sobre a disparidade salarial observada
print("logo, há evidência de disparidade salarial entre gêneros biológicos neste dataset, pois A proporção de homens ganhando acima de 50K é quase 3 vezes maior que a das mulheres como mostram os dados")
logo, há evidência de disparidade salarial entre gêneros biológicos neste dataset, pois A proporção de homens ganhando acima de 50K é quase 3 vezes maior que a das mulheres como mostram os dados

##horario do html

# Captura o horário atual
horario_geracao <- Sys.time()

# Mostrar no console
horario_geracao
[1] "2025-10-07 11:12:37 -03"
# Ou inserir em um HTML (exemplo com cat)
cat("<p>Relatório gerado em:", horario_geracao, "</p>")
<p>Relatório gerado em: 1759846357 </p>