Introdução

Este relatório cria e analisa uma série temporal a partir do arquivo sunspots.csv. Ele executa: 1. Leitura robusta do CSV 2. Limpeza de valores e conversão numérica 3. Criação do objeto ts() (opção para overrides de frequência e início) 4. Análise exploratória (média, mediana, variância, skew, kurtosis, ACF lag-1) 5. Gráficos: série temporal, histograma, boxplot 6. Uso de window() para criar série reduzida e salvá-la 7. Repetição das análises em séries nativas do R: austres, fdeaths, co2

# ---------- Setup: pacotes, opções e caminhos ----------
# Instalar pacotes se necessário
if(!requireNamespace("readr", quietly = TRUE)) install.packages("readr")
if(!requireNamespace("moments", quietly = TRUE)) install.packages("moments")
if(!requireNamespace("zoo", quietly = TRUE)) install.packages("zoo")   # para interpolação opcional

library(readr)
library(moments)
library(zoo)
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(datasets)

# Opcional: force frequency/start se souber (descomente e ajuste)
# freq_override <- 12
# start_override <- c(1749, 1)
freq_override <- NULL
start_override <- NULL

# Caminhos padrão para tentar localizar o CSV (ajuste se necessário)
default_csv_paths <- c(
  "sunspots.csv",
  "C:/Users/aless/Downloads/Modelagem Preditiva/Relatorio/sunspots.csv"
)

# Ajuste do working directory para pasta do Rmd quando em RStudio (interativo)
if (interactive() && requireNamespace("rstudioapi", quietly = TRUE)) {
  rmd_path <- tryCatch(dirname(rstudioapi::getActiveDocumentContext()$path),
                       error = function(e) NULL)
  if (!is.null(rmd_path) && nzchar(rmd_path)) {
    setwd(rmd_path)
  }
}
cat("Working directory:", getwd(), "\n")
## Working directory: C:/Users/aless/Downloads/Modelagem Preditiva/Relatorio/R markdown
cat("Arquivos nesta pasta:\n"); print(list.files())
## Arquivos nesta pasta:
## [1] "Relatorio.html"                  "Relatorio.Rmd"                  
## [3] "rsconnect"                       "sunspots.csv"                   
## [5] "sunspots_reduced_R_reduced2.csv"

Localizar e ler o arquivo CSV sunsposts.csv

# Tenta localizar arquivo nos caminhos padrão
csv_path <- NULL
for (p in default_csv_paths) {
  if (file.exists(p)) { csv_path <- p; break }
}
if (is.null(csv_path)) {
  stop("Arquivo sunspots.csv não encontrado nos caminhos padrão. Coloque o arquivo no diretório do Rmd ou ajuste default_csv_paths.")
}
cat("Lendo arquivo:", csv_path, "\n")
## Lendo arquivo: sunspots.csv
# Leitura robusta com readr (vroom) e fallback
df <- NULL
try({
  df <- readr::read_csv(csv_path, show_col_types = FALSE)
}, silent = TRUE)
## Warning: One or more parsing issues, call `problems()` on your data frame for details,
## e.g.:
##   dat <- vroom(...)
##   problems(dat)
if (is.null(df)) {
  try({
    df <- readr::read_csv2(csv_path, show_col_types = FALSE)  # sep=';'
  }, silent = TRUE)
}

if (is.null(df)) {
  # última tentativa: usar base R read.csv
  try({
    df <- utils::read.csv(csv_path, header = TRUE, stringsAsFactors = FALSE)
  }, silent = TRUE)
}

if (is.null(df)) stop("Não foi possível ler o CSV automaticamente. Verifique o arquivo (separador/encoding).")

cat("Colunas detectadas:", paste(names(df), collapse = ", "), "\n")
## Colunas detectadas: x
print(head(df, 10))
## # A tibble: 10 × 1
##        x
##    <dbl>
##  1  158 
##  2  263.
##  3  370 
##  4  456.
##  5  585 
##  6  684.
##  7  795.
##  8  866.
##  9  976.
## 10 1076.
# Se readr reportou parsing issues: você pode inspecionar com problems(df)

Diagnóstico e limpeza dos dados

# Diagnóstico
if (exists("problems")) {
  try({ print(problems(df)) }, silent = TRUE)
}
## # A tibble: 2,820 × 5
##      row   col expected  actual    file                                         
##    <int> <int> <chr>     <chr>     <chr>                                        
##  1     2     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  2     3     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  3     4     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  4     5     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  5     6     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  6     7     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  7     8     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  8     9     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
##  9    10     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
## 10    11     2 1 columns 2 columns C:/Users/aless/Downloads/Modelagem Preditiva…
## # ℹ 2,810 more rows
str(df)
## spc_tbl_ [2,820 × 1] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ x: num [1:2820] 158 263 370 456 585 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   x = col_number()
##   .. )
##  - attr(*, "problems")=<externalptr>
print(head(df, 30))
## # A tibble: 30 × 1
##        x
##    <dbl>
##  1  158 
##  2  263.
##  3  370 
##  4  456.
##  5  585 
##  6  684.
##  7  795.
##  8  866.
##  9  976.
## 10 1076.
## # ℹ 20 more rows
# Identificar coluna de valores (primeira coluna por padrão)
col <- names(df)[1]
cat("Coluna usada como valores:", col, "\n")
## Coluna usada como valores: x
cat("Classe original:", class(df[[col]]), "\n")
## Classe original: numeric
# Limpeza genérica: remover espaços, remover ponto final '263.' -> '263', manter sinais e vírgula/ponto
cleaned <- gsub("\\s+", "", as.character(df[[col]]))       # remove espaços
cleaned <- gsub("\\.(?=$)", "", cleaned, perl = TRUE)      # remove ponto final se estiver no final
cleaned <- gsub("[^0-9,\\.-]", "", cleaned)                # remove chars indesejados
cleaned <- gsub(",", ".", cleaned)                         # vírgula decimal -> ponto
numeric_vals <- as.numeric(cleaned)

# Mostrar resultado preliminar
cat("Resumo após limpeza (numeric_vals):\n")
## Resumo após limpeza (numeric_vals):
print(summary(numeric_vals))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     158   25915  130269  335967  229108 2808127
cat("NAs após conversão:", sum(is.na(numeric_vals)), "\n")
## NAs após conversão: 0
head(numeric_vals, 20)
##  [1]   158.0   262.6   370.0   455.7   585.0   683.5   794.8   866.3   975.9
## [10]  1075.5 11158.6  1285.2  1373.3  1475.9  1589.2  1688.3  1790.0 18100.0
## [19]  1985.4 20103.0
# Substituir coluna no df por versão numérica limpa
df[[col]] <- numeric_vals

# Opcional: interpolar NAs internos (não interpola NAs no início/fim)
if (sum(is.na(df[[col]])) > 0) {
  # comentar ou descomentar dependendo do que desejar
  df[[col]] <- zoo::na.approx(df[[col]], na.rm = FALSE)
  cat("Após interpolação, NAs restantes:", sum(is.na(df[[col]])), "\n")
}

Criar objeto ts() (série temporal)

# Criar vetor de valores a partir da coluna limpa
valores <- df[[col]]

# criar ts com overrides se definidos
if (!is.null(freq_override) && !is.null(start_override)) {
  ts_sun <- ts(valores, start = start_override, frequency = freq_override)
  cat("ts criado com overrides: start =", paste(start_override, collapse=","), " freq=", freq_override, "\n")
} else if (!is.null(freq_override)) {
  ts_sun <- ts(valores, start = 1, frequency = freq_override)
  cat("ts criado com frequency override =", freq_override, " start=1\n")
} else {
  ts_sun <- ts(valores, start = 1, frequency = 1)
  cat("ts criado com fallback: start=1, frequency=1\n")
}
## ts criado com fallback: start=1, frequency=1
# resumo
cat("Série criada: comprimento =", length(ts_sun), 
    "; start =", paste(start(ts_sun), collapse=","), 
    " end =", paste(end(ts_sun), collapse=","), 
    " frequency =", frequency(ts_sun), "\n")
## Série criada: comprimento = 2820 ; start = 1,1  end = 2820,1  frequency = 1
summary(ts_sun)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     158   25915  130269  335967  229108 2808127

Análise exploratória (média, mediana, variância, skew, kurtosis, ACF lag-1)

mean_val <- mean(ts_sun, na.rm = TRUE)
median_val <- median(ts_sun, na.rm = TRUE)
var_val <- var(ts_sun, na.rm = TRUE)
sd_val <- sd(ts_sun, na.rm = TRUE)
qnts <- quantile(ts_sun, probs = c(0.25,0.5,0.75), na.rm = TRUE)
skew_val <- moments::skewness(as.numeric(ts_sun), na.rm = TRUE)
kurt_val <- moments::kurtosis(as.numeric(ts_sun), na.rm = TRUE)

acf_res <- acf(ts_sun, plot = FALSE)
acf_lag1 <- as.numeric(acf_res$acf[2])

cat(sprintf("Mean: %.6g\n", mean_val))
## Mean: 335967
cat(sprintf("Median: %.6g\n", median_val))
## Median: 130269
cat(sprintf("Variance: %.6g    SD: %.6g\n", var_val, sd_val))
## Variance: 4.32122e+11    SD: 657360
cat("25% / 50% / 75%:\n"); print(qnts)
## 25% / 50% / 75%:
##       25%       50%       75% 
##  25914.58 130269.10 229108.10
cat(sprintf("Skewness: %.6g    Kurtosis: %.6g\n", skew_val, kurt_val))
## Skewness: 2.79014    Kurtosis: 9.44587
cat(sprintf("ACF lag-1: %.6g\n", acf_lag1))
## ACF lag-1: 0.816399

Gráficos: série temporal, histograma, boxplot

(Os plots são capturados automaticamente pelo knitr e incluídos no HTML.)

# série temporal
plot.ts(ts_sun, main = "Sunspots - Serie Temporal", ylab = "Valor", xlab = "Tempo")

# histograma
hist(as.numeric(ts_sun), breaks = 30, main = "Histograma - Sunspots", xlab = "Valor")

# boxplot
boxplot(as.numeric(ts_sun), main = "Boxplot - Sunspots", ylab = "Valor")

# Usar window() para criar uma série reduzida e salvar

cat("Length da série:", length(ts_sun), "\n")
## Length da série: 2820
if (frequency(ts_sun) > 1) {
  tt <- time(ts_sun)
  if (min(tt) <= 1900 && max(tt) >= 1950) {
    reduced1 <- tryCatch(window(ts_sun, start = c(1900,1), end = c(1950, frequency(ts_sun))), error = function(e) NULL)
    if (!is.null(reduced1)) cat("reduced1 criado com window(1900-1950)\n")
  } else {
    cat("Intervalo 1900-1950 não aplicável — ignorado.\n")
    reduced1 <- NULL
  }
} else {
  cat("frequency = 1 -> corte por índices (metade final como exemplo)\n")
  n <- length(ts_sun)
  start_index <- floor(n/2) + 1
  time_vec <- time(ts_sun)
  start_time <- time_vec[start_index]
  reduced2 <- window(ts_sun, start = start_time)
  cat("reduced2 criado a partir do índice", start_index, "\n")
}
## frequency = 1 -> corte por índices (metade final como exemplo)
## reduced2 criado a partir do índice 1411
# salvar a série reduzida
if (exists("reduced1") && !is.null(reduced1)) {
  write.csv(data.frame(value = as.numeric(reduced1)), file = "sunspots_reduced_R_reduced1.csv", row.names = FALSE)
  cat("Salvo: sunspots_reduced_R_reduced1.csv\n")
} else if (exists("reduced2") && !is.null(reduced2)) {
  write.csv(data.frame(value = as.numeric(reduced2)), file = "sunspots_reduced_R_reduced2.csv", row.names = FALSE)
  cat("Salvo: sunspots_reduced_R_reduced2.csv\n")
} else {
  cat("Nenhuma série reduzida salva.\n")
}
## Salvo: sunspots_reduced_R_reduced2.csv

Repetir para séries nativas: austres, fdeaths, co2

# austres
data(austres)
cat("=== austres ===\n"); print(summary(austres))
## === austres ===
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   13067   14110   15184   15273   16399   17662
plot(austres, main = "austres - Serie Temporal")

hist(as.numeric(austres), main = "Histograma - austres")

boxplot(as.numeric(austres), main = "Boxplot - austres")

# fdeaths
data(fdeaths)
## Warning in data(fdeaths): data set 'fdeaths' not found
cat("=== fdeaths ===\n"); print(summary(fdeaths))
## === fdeaths ===
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   330.0   411.0   512.0   560.7   681.5  1141.0
plot(fdeaths, main = "fdeaths - Serie Temporal")

hist(as.numeric(fdeaths), main = "Histograma - fdeaths")

boxplot(as.numeric(fdeaths), main = "Boxplot - fdeaths")

# co2
data(co2)
cat("=== co2 ===\n"); print(summary(co2))
## === co2 ===
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   313.2   323.5   335.2   337.1   350.3   366.8
plot(co2, main = "co2 - Serie Temporal")

hist(as.numeric(co2), main = "Histograma - co2")

boxplot(as.numeric(co2), main = "Boxplot - co2")