################################################################
# AULA 04 - MANIPULANDO OBJETOS
# DISCIPLINA: EAIT
# MESTRADO PROFISSIONAL EM TECNOLOGIAS E INOVACOES CONSTRUTIVAS
# Prof. Ben Deivide | UFSJ
# https://bendeivide.github.io/courses/eait
################################################################

############################################################
# Aula: Manipulação de objetos em R (Base R)
############################################################

## -------------------------------
## 1. Vetores
## -------------------------------

# Criando vetores
notas <- c(7.5, 8.0, 6.5, 9.0, 5.5); notas
alunos <- c("Ana", "Bruno", "Carlos", "Daniela", "Eduardo")
alunos
# Nomeando elementos
names(notas) <- alunos; notas

# Modificando apenas um nome do vetor (ex.: o segundo elemento)
names(notas)[2] <- "Jair"
notas


# Operacoes vetoriais
media <- mean(notas); media

# Indexacao
notas[1]           # primeiro elemento
notas["Ana"]       # por nome

# Indexacao logica
aprovados <- notas >= 7
aprovados
# Quem foi aprovado?
notas[aprovados]
# Quem foi reprovado?
notas[!aprovados]

## -------------------------------
## 2. Data Frame
## -------------------------------

dados <- data.frame(
  aluno = alunos,
  matematica = c(7.5, 8.0, 6.5, 9.0, 5.5),
  estatistica = c(8.0, 7.5, 6.0, 9.5, 6.0),
  programacao = c(7.0, 8.5, 7.0, 9.0, 5.0)
)

# Visualização
dados
str(dados)
summary(dados)

# Acessando colunas
dados$matematica
dados[, "estatistica"]
dados[, 2] # matematica

## -------------------------------
## 3. Subconjuntos
## -------------------------------

# Alunos com nota >= 7 em matemática
subset(dados, matematica >= 7)
dados |>
  subset(matematica >= 7) |>
  summary()
## Forma sintatica nativa antes do pipe
res1 <- subset(dados, matematica >= 7)
res2 <- summary(res1)
res2
# Selecionando colunas específicas
subset(dados, select = c(aluno, programacao))
subset(dados, programacao >= 8, select = c(aluno, programacao))
## De forma nativa
dados$programacao[dados$programacao >= 8]
# Condicao multipla
subset(dados, matematica >= 7 & estatistica >= 7)

## -------------------------------
## 4. apply()
## -------------------------------

# Media por linha (por aluno)
apply(dados[, 2:4], 1, mean)

# Media por coluna (por disciplina)
apply(dados[, 2:4], 2, mean)

## -------------------------------
## 5. lapply() e sapply()
## -------------------------------

# Lista com colunas numericas
lista_notas <- dados[, 2:4]

# lapply: retorna lista
lapply(lista_notas, mean)

# sapply: simplifica resultado
sapply(lista_notas, mean) # Media por coluna
sapply(lista_notas, summary) # Resumo por coluna

## -------------------------------
## 6. Criando nova variavel
## -------------------------------

# Media geral por aluno
dados$media <- apply(dados[, 2:4], 1, mean)

# Situacao do aluno
dados$situacao <- ifelse(dados$media >= 7, "Aprovado", "Reprovado")
dados

## -------------------------------
## 7. Problema aplicado
## -------------------------------

# Perguntas:

# 1. Qual disciplina tem maior média?
medias <- sapply(dados[, 2:4], mean)
medias
# Qual?
names(which.max(medias))

# 2. Quantos alunos foram aprovados?
sum(dados$situacao == "Aprovado")

# 3. Quais alunos tem media acima da media geral?
media_geral <- mean(dados$media)
#
subset(dados, media > media_geral)


## -------------------------------
## 8. Controle de fluxo
## -------------------------------

## Reutilizando o data frame anterior
dados

## -------------------------------
## 8.1 Estrutura if
## -------------------------------

# Verificar situacao de um aluno especifico
nota_media_ana <- dados$media[1]

if (nota_media_ana >= 7) {
  print("Ana esta aprovada")
} else {
  print("Ana esta reprovada")
}

## -------------------------------
## 8.2 Usando if dentro de loop
## -------------------------------

# Classificando alunos manualmente (sem ifelse)
situacao_manual <- character(nrow(dados))

for (i in 1:nrow(dados)) {
  if (dados$media[i] >= 7) {
    situacao_manual[i] <- "Aprovado"
  } else {
    situacao_manual[i] <- "Reprovado"
  }
}

situacao_manual

## Comparando com resultado vetorizado
dados$situacao
situacao_manual

## -------------------------------
## 8.3 Estrutura for
## -------------------------------

# Calculando media manualmente (sem apply)
media_manual <- numeric(nrow(dados))

for (i in 1:nrow(dados)) {
  soma <- 0
  for (j in 2:4) {
    soma <- soma + dados[i, j]
  }
  media_manual[i] <- soma / 3
}

media_manual
dados$media

## -------------------------------
## 8.4 Estrutura while
## -------------------------------

# Simulando crescimento da media ate atingir um valor alvo
media_simulada <- 5
incremento <- 0.3
iteracoes <- 0

while (media_simulada < 7) {
  media_simulada <- media_simulada + incremento
  iteracoes <- iteracoes + 1
}

media_simulada
iteracoes

## -------------------------------
## 8.5 Exemplo aplicado com for + if
## -------------------------------

# Encontrar alunos com media acima da media geral
media_geral <- mean(dados$media)

alunos_acima_media <- c()

for (i in 1:nrow(dados)) {
  if (dados$media[i] > media_geral) {
    alunos_acima_media <- c(alunos_acima_media, dados$aluno[i])
  }
}

alunos_acima_media

## -------------------------------
## 8.6 Comparação: for vs apply
## -------------------------------

# Usando for
medias_for <- numeric(ncol(dados[,2:4]))

for (i in 1:ncol(dados[,2:4])) {
  medias_for[i] <- mean(dados[,2:4][, i])
}

medias_for

# Usando apply
medias_apply <- apply(dados[,2:4], 2, mean); medias_apply

# Usando sapply
medias_sapply <- sapply(dados[,2:4], mean); medias_sapply

## -------------------------------
## 9. Base de dados: pacote datasets
## -------------------------------

# library(datasets)
dados <- penguins; dados
## Os dados foram coletados no arquipelago Palmer, 
## na Antartica, por meio do projeto ecologico conduzido 
## pela Palmer Station LTER (Long Term Ecological Research).
##
##   Número de observacoes: 344 pinguins
##   Número de variaveis: 8
##   Tipo: data frame
##   Cada linha representa um pinguim observado.
##
## 🧾 Variaveis da base

### 🔹 Variaveis categoricas (qualitativas)
# - **`species`**  
#   Especie do pinguim:
#   - Adelie  
#   - Chinstrap  
#   - Gentoo
# - **`island`**  
#   Ilha onde o pinguim foi observado:
#   - Biscoe  
#   - Dream  
#   - Torgersen  
# - **`sex`**  
#   Sexo do pinguim:
#   - male  
#   - female  
# *(com valores ausentes em alguns casos)*
### 🔹 Variaveis numericas (quantitativas)
# - **`bill_length_mm`**  
#   Comprimento do bico (mm)
# - **`bill_depth_mm`**  
#   Profundidade do bico (mm)
# - **`flipper_length_mm`**  
#   Comprimento da nadadeira (mm)
# - **`body_mass_g`**  
#   Massa corporal (gramas)
# ### 🔹 Variavel adicional
# - **`year`**  
#   Ano da observacao (2007, 2008 ou 2009)
## ⚠️ Valores ausentes
# A base contem alguns valores faltantes (`NA`), especialmente em:
#   - `sex`
#   - medicoes fisicas


# Visualizacao inicial
head(dados) # Visualiza
str(dados)
summary(dados)

## -------------------------------
## 9.1 Limpeza de dados
## -------------------------------

# Remover linhas com NA
dados_limpos <- na.omit(dados)

nrow(dados)
nrow(dados_limpos)

## -------------------------------
## 9.2 Subconjuntos
## -------------------------------

# Apenas pinguins da especie Adelie
adelie <- subset(dados_limpos, species == "Adelie")

# Apenas ilha Biscoe
biscoe <- subset(dados_limpos, island == "Biscoe")

## -------------------------------
## 9.3 Estatisticas por grupo
## -------------------------------

# Media do comprimento do bico por especie
tapply(dados_limpos$bill_len,
       dados_limpos$species,
       mean)

# Massa media por sexo
tapply(dados_limpos$body_mass,
       dados_limpos$sex,
       mean)

## -------------------------------
## 9.4 Usando aggregate()
## -------------------------------

# Media de multiplas variaveis por especie
aggregate(cbind(bill_len, flipper_len, body_mass) ~ species,
          data = dados_limpos,
          FUN = mean)

# Media por especie e sexo
aggregate(body_mass ~ species + sex,
          data = dados_limpos,
          FUN = mean)

## -------------------------------
## 9.5 Usando split() + lapply()
## -------------------------------

# Dividindo por especie
dados_split <- split(dados_limpos, dados_limpos$species)

# Media da massa em cada grupo
lapply(dados_split, function(df) mean(df$body_mass))

# Numero de observacoes por grupo
sapply(dados_split, nrow)

## -------------------------------
## 9.6 Criando variaveis derivadas
## -------------------------------

# Indice simples (relacao bico/comprimento nadadeira)
dados_limpos$indice <- dados_limpos$bill_len / dados_limpos$flipper_len
head(dados_limpos) # primeiros dados
# Classificacao com ifelse
dados_limpos$tamanho <- ifelse(dados_limpos$body_mass > 4000,
                               "Grande",
                               "Pequeno")
head(dados_limpos) # primeiros dados
table(dados_limpos$tamanho)

## -------------------------------
## 9.7 Aplicacao com apply
## -------------------------------

# Media das variaveis numericas por linha
dados_limpos$media_medidas <- apply(dados_limpos[, c("bill_len",
                                                     "bill_dep",
                                                     "flipper_len",
                                                     "body_mass")],
                                    1, mean)
head(dados_limpos)
## -------------------------------
## 9.8 Controle de fluxo (for + if)
## -------------------------------

# Identificar pinguins com massa acima da media da especie

dados_limpos$acima_media <- FALSE

for (i in 1:nrow(dados_limpos)) {
  
  especie <- dados_limpos$species[i]
  
  media_especie <- mean(dados_limpos$body_mass[dados_limpos$species == especie])
  
  if (dados_limpos$body_mass[i] > media_especie) {
    dados_limpos$acima_media[i] <- TRUE
  }
}

table(dados_limpos$acima_media)

## -------------------------------
## 9.9 Problema aplicado
## -------------------------------

# Qual especie tem maior massa media?
medias_especie <- tapply(dados_limpos$body_mass,
                         dados_limpos$species,
                         mean)

medias_especie
names(which.max(medias_especie))

# Qual combinacao especie + sexo tem maior media?
medias_grupo <- aggregate(body_mass ~ species + sex,
                          data = dados_limpos,
                          mean)

medias_grupo

medias_grupo[which.max(medias_grupo$body_mass), ]


## -------------------------------
## 10. Funcoes adicionais (base R)
## -------------------------------

## Reutilizando dados_limpos (penguins)

head(dados_limpos)

## -------------------------------
## 10.1 with()
## -------------------------------

# Evita repeticao do nome do data frame
with(dados_limpos, mean(body_mass))

# Comparacao por especie
with(dados_limpos,
     tapply(body_mass_g, species, mean))

## -------------------------------
## 10.2 by()
## -------------------------------

# Aplicar funcao por grupo
by(dados_limpos$body_mass_g,
   dados_limpos$species,
   mean)

# Mais complexo: media de multiplas variaveis por especie
by(dados_limpos[, c("bill_length_mm", "flipper_length_mm")],
   dados_limpos$species,
   colMeans)

## -------------------------------
## 10.3 within()
## -------------------------------

# Criando novas variaveis de forma organizada
dados2 <- within(dados_limpos, {
  
  media_medidas2 <- (bill_len + bill_dep +
                       flipper_len + body_mass) / 4
  
  categoria_massa <- ifelse(body_mass > 4000,
                            "Grande",
                            "Pequeno")
})

head(dados2)

## -------------------------------
## 10.4 ave()
## -------------------------------

# Media da massa por grupo (mesmo tamanho do vetor original)
dados_limpos$media_por_especie <- ave(dados_limpos$body_mass,
                                      dados_limpos$species,
                                      FUN = mean)

head(dados_limpos[, c("species", "body_mass_g", "media_por_especie")])

## Comparando individuo com sua media
dados_limpos$acima_media2 <- dados_limpos$body_mass_g >
  dados_limpos$media_por_especie

table(dados_limpos$acima_media2)

## -------------------------------
## 10.5 Comparacao entre abordagens
## -------------------------------

# tapply
tapply(dados_limpos$body_mass,
       dados_limpos$species,
       mean)

# by
by(dados_limpos$body_mass,
   dados_limpos$species,
   mean)

# aggregate
aggregate(body_mass ~ species,
          data = dados_limpos,
          mean)

## -------------------------------
## 10.6 Problema aplicado
## -------------------------------

# Identificar indivíduos com massa acima da média da espécie
# usando ave (forma mais elegante)

dados_limpos$acima_media3 <-
  with(dados_limpos,
       body_mass > ave(body_mass, species, FUN = mean))

table(dados_limpos$acima_media3)



