1 Leitura do arquivo e definição dos fatores

Bloco inicial baseado no seu script.
Lê CSV com sep=";" e dec=",", remove 2 colunas específicas, e define os fatores.

#### ANAVAS CLIMA (baseado no script_3.R)
dados_2 <- read.table(params$data_path, header = TRUE, sep = ";", dec = ",")

# Remove colunas (se existirem)
cols_drop <- c("Pressão.de.vapor.de.saturação..kPa.", "Pressão.atual.de.vapor.de.água..kPa.")
for(cd in cols_drop){
  if(cd %in% names(dados_2)) dados_2[[cd]] <- NULL
}

# Fatores
dados_2$Ambiente  <- as.factor(dados_2$Ambiente)
dados_2$Estação   <- as.factor(dados_2$Estação)
dados_2$Repetição <- as.factor(dados_2$Repetição)  # não será usada no modelo (DIC)

str(dados_2)
## 'data.frame':    450 obs. of  9 variables:
##  $ Ambiente                                 : Factor w/ 3 levels "AD","FL","PM": 3 3 3 3 3 3 3 3 3 3 ...
##  $ Estação                                  : Factor w/ 3 levels "EMC","ET","FEC": 3 3 3 3 3 3 3 3 3 3 ...
##  $ Repetição                                : Factor w/ 60 levels "1","2","3","4",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ Temperatura.média.do.ar...C.             : num  26.1 26.6 27.8 28.4 28.3 ...
##  $ Temperatura.máxima.do.ar...C.            : num  30 30.9 30.9 30.6 30.5 ...
##  $ Temperatura.mínima.do.ar...C.            : num  23.6 23.6 24.4 26.6 26.1 ...
##  $ Amplitude.térmica.do.ar...C.             : num  6.41 7.34 6.51 4.06 4.48 4.4 5.71 4.89 7.1 7.62 ...
##  $ UH....                                   : num  84.6 84.2 79.9 77 75.7 ...
##  $ Déficit.de.pressão.de.vapor.de.água..kPa.: num  0.52 0.55 0.75 0.89 0.94 0.98 0.9 0.55 0.45 0.55 ...

2 Variáveis resposta (numéricas)

# Evita problemas de versão do dplyr (where()) e/ou conflitos de select()
# Seleção robusta via base R:
resp_vars <- names(dados_2)[vapply(dados_2, is.numeric, logical(1))]

resp_vars
## [1] "Temperatura.média.do.ar...C."             
## [2] "Temperatura.máxima.do.ar...C."            
## [3] "Temperatura.mínima.do.ar...C."            
## [4] "Amplitude.térmica.do.ar...C."             
## [5] "UH...."                                   
## [6] "Déficit.de.pressão.de.vapor.de.água..kPa."

3 Modelo estatístico

Modelo solicitado (DIC, sem efeito de repetição/bloco):

Observação: essa escrita é equivalente a variável ~ Ambiente * Estação (efeitos principais + interação).

4 ANAVA + Tukey para cada variável

4.1 Funções auxiliares

# Converte p-valor em símbolos (ns, *, **, ***)
p_to_sig <- function(p){
  if(is.na(p)) return(NA_character_)
  if(p < 0.001) return("***")
  if(p < 0.01)  return("**")
  if(p < 0.05)  return("*")
  return("ns")
}

# Letras compactas do Tukey (emmeans) para um fator
get_cld_letters <- function(fit, fac){
  # fit: objeto aov()
  # fac: string com o nome do fator, ex "Ambiente" ou "Estação"

  emm <- emmeans::emmeans(fit, specs = fac)

  # cld() retorna um data.frame com a coluna do fator (com nome = fac) e a coluna ".group"
  cld_df <- as.data.frame(multcomp::cld(emm, Letters = letters, adjust = "tukey"))

  if(!(fac %in% names(cld_df))){
    stop(paste0("Coluna do fator '", fac, "' não encontrada no resultado do cld()."))
  }
  if(!(".group" %in% names(cld_df))){
    stop("Coluna '.group' não encontrada no resultado do cld().")
  }

  out <- cld_df[, c(fac, ".group"), drop = FALSE]
  out$.group <- gsub("\\s+", "", out$.group)
  out
}


# Média e desvio por fator
mean_sd_by <- function(df, y, fac){
  df %>%
    group_by(.data[[fac]]) %>%
    summarise(
      media = mean(.data[[y]], na.rm = TRUE),
      desvio = sd(.data[[y]], na.rm = TRUE),
      .groups = "drop"
    ) %>%
    rename(!!fac := 1)
}

4.2 Loop de análises

resultados <- list()
tabelas_amb <- list()
tabelas_est <- list()

for(v in resp_vars){

  # Ajuste do modelo: y ~ Ambiente * Estação (sem Repetição)
  form <- as.formula(paste0("`", v, "` ~ `Ambiente` * `Estação`"))
  fit <- aov(form, data = dados_2)

  # ANOVA (base R)
  an_tab <- anova(fit)   # mais direto que summary(fit)[[1]]
termos <- rownames(an_tab)
pvals  <- an_tab[["Pr(>F)"]]

# helpers robustos
pick_p <- function(pattern){
  idx <- grep(pattern, termos)
  if(length(idx) == 0) return(NA_real_)
  pvals[idx[1]]
}

p_amb <- pick_p("^Ambiente$")                # exatamente Ambiente
p_est <- pick_p("^Est")                      # pega Estação mesmo com encoding/variações
p_int <- pick_p("Ambiente.*:.*Est|Est.*:.*Ambiente")  # interação, bem tolerante


  # Tukey (emmeans) por fator
  cld_amb <- get_cld_letters(fit, "Ambiente")  # data.frame: Ambiente, .group
  cld_est <- get_cld_letters(fit, "Estação")   # data.frame: Estação, .group

  # Média ± sd por fator (base R)
  # Ambiente
  ms_amb <- aggregate(dados_2[[v]], list(Ambiente = dados_2$Ambiente),
                      function(x) c(media = mean(x, na.rm=TRUE), desvio = sd(x, na.rm=TRUE)))
  ms_amb <- do.call(data.frame, ms_amb)
  names(ms_amb)[2:3] <- c("media", "desvio")

  # Estação
  ms_est <- aggregate(dados_2[[v]], list(Estação = dados_2$Estação),
                      function(x) c(media = mean(x, na.rm=TRUE), desvio = sd(x, na.rm=TRUE)))
  ms_est <- do.call(data.frame, ms_est)
  names(ms_est)[2:3] <- c("media", "desvio")

  # Junta com letras (merge base R)
  tab_amb <- merge(ms_amb, cld_amb, by = "Ambiente", all.x = TRUE)
  tab_amb$var <- v
  tab_amb$media_sd <- sprintf("%.3f $\\pm$ %.3f", tab_amb$media, tab_amb$desvio)
  tab_amb$letra <- tab_amb$.group
  tab_amb <- tab_amb[, c("var", "Ambiente", "media_sd", "letra")]

  tab_est <- merge(ms_est, cld_est, by = "Estação", all.x = TRUE)
  tab_est$var <- v
  tab_est$media_sd <- sprintf("%.3f $\\pm$ %.3f", tab_est$media, tab_est$desvio)
  tab_est$letra <- tab_est$.group
  tab_est <- tab_est[, c("var", "Estação", "media_sd", "letra")]

  tabelas_amb[[v]] <- tab_amb
  tabelas_est[[v]] <- tab_est

  resultados[[v]] <- data.frame(
    variavel = v,
    p_Ambiente = p_amb,
    sig_Ambiente = p_to_sig(p_amb),
    p_Estacao = p_est,
    sig_Estacao = p_to_sig(p_est),
    p_Interacao = p_int,
    sig_Interacao = p_to_sig(p_int),
    stringsAsFactors = FALSE
  )
}

# Junta resultados (base R)
res_anova <- do.call(rbind, resultados)
res_anova
##                                                                            variavel
## Temperatura.média.do.ar...C.                           Temperatura.média.do.ar...C.
## Temperatura.máxima.do.ar...C.                         Temperatura.máxima.do.ar...C.
## Temperatura.mínima.do.ar...C.                         Temperatura.mínima.do.ar...C.
## Amplitude.térmica.do.ar...C.                           Amplitude.térmica.do.ar...C.
## UH....                                                                       UH....
## Déficit.de.pressão.de.vapor.de.água..kPa. Déficit.de.pressão.de.vapor.de.água..kPa.
##                                              p_Ambiente sig_Ambiente
## Temperatura.média.do.ar...C.               1.635765e-25          ***
## Temperatura.máxima.do.ar...C.             3.268515e-205          ***
## Temperatura.mínima.do.ar...C.              1.425486e-29          ***
## Amplitude.térmica.do.ar...C.              1.650327e-194          ***
## UH....                                     4.615990e-61          ***
## Déficit.de.pressão.de.vapor.de.água..kPa.  6.994293e-53          ***
##                                              p_Estacao sig_Estacao  p_Interacao
## Temperatura.média.do.ar...C.              9.306264e-04         *** 2.095191e-34
## Temperatura.máxima.do.ar...C.             1.156662e-19         *** 1.014755e-20
## Temperatura.mínima.do.ar...C.             4.294587e-32         *** 7.398119e-01
## Amplitude.térmica.do.ar...C.              8.389473e-03          ** 2.140156e-11
## UH....                                    3.969056e-52         *** 2.068233e-02
## Déficit.de.pressão.de.vapor.de.água..kPa. 1.512323e-48         *** 4.671608e-02
##                                           sig_Interacao
## Temperatura.média.do.ar...C.                        ***
## Temperatura.máxima.do.ar...C.                       ***
## Temperatura.mínima.do.ar...C.                        ns
## Amplitude.térmica.do.ar...C.                        ***
## UH....                                                *
## Déficit.de.pressão.de.vapor.de.água..kPa.             *

4.3 Resumo das ANAVAs

res_anova %>%
  mutate(across(starts_with("p_"), ~ signif(.x, 4))) %>%
  kable(caption = "Significâncias da ANAVA (modelo: variável ~ Ambiente * Estação).") %>%
  kable_styling(full_width = FALSE)
Significâncias da ANAVA (modelo: variável ~ Ambiente * Estação).
variavel p_Ambiente sig_Ambiente p_Estacao sig_Estacao p_Interacao sig_Interacao
Temperatura.média.do.ar…C. Temperatura.média.do.ar…C. 0 *** 0.0009306 *** 0.00000 ***
Temperatura.máxima.do.ar…C. Temperatura.máxima.do.ar…C. 0 *** 0.0000000 *** 0.00000 ***
Temperatura.mínima.do.ar…C. Temperatura.mínima.do.ar…C. 0 *** 0.0000000 *** 0.73980 ns
Amplitude.térmica.do.ar…C. Amplitude.térmica.do.ar…C. 0 *** 0.0083890 ** 0.00000 ***
UH…. UH…. 0 *** 0.0000000 *** 0.02068
Déficit.de.pressão.de.vapor.de.água..kPa. Déficit.de.pressão.de.vapor.de.água..kPa. 0 *** 0.0000000 *** 0.04672

5 Tabela final em LaTeX (médias ± desvios + letras + significâncias)

tab_amb_all <- do.call(rbind, tabelas_amb)
tab_est_all <- do.call(rbind, tabelas_est)

tab_amb_wide <- tab_amb_all %>%
  dplyr::mutate(val = paste0(media_sd, " (", letra, ")")) %>%
  dplyr::select(var, Ambiente, val) %>%
  tidyr::pivot_wider(names_from = Ambiente, values_from = val)

tab_est_wide <- tab_est_all %>%
  dplyr::mutate(val = paste0(media_sd, " (", letra, ")")) %>%
  dplyr::select(var, Estação, val) %>%
  tidyr::pivot_wider(names_from = Estação, values_from = val)

tabela_final <- res_anova %>%
  dplyr::select(variavel, sig_Ambiente, sig_Estacao, sig_Interacao) %>%
  dplyr::rename(var = variavel) %>%
  dplyr::left_join(tab_amb_wide, by = "var") %>%
  dplyr::left_join(tab_est_wide, by = "var")

tabela_final
##                                         var sig_Ambiente sig_Estacao
## 1              Temperatura.média.do.ar...C.          ***         ***
## 2             Temperatura.máxima.do.ar...C.          ***         ***
## 3             Temperatura.mínima.do.ar...C.          ***         ***
## 4              Amplitude.térmica.do.ar...C.          ***          **
## 5                                    UH....          ***         ***
## 6 Déficit.de.pressão.de.vapor.de.água..kPa.          ***         ***
##   sig_Interacao                      AD                      FL
## 1           *** 28.730 $\\pm$ 1.047 (c) 28.003 $\\pm$ 1.093 (b)
## 2           *** 36.347 $\\pm$ 1.630 (b) 30.605 $\\pm$ 1.298 (a)
## 3            ns 24.170 $\\pm$ 1.417 (a) 25.255 $\\pm$ 1.159 (b)
## 4           *** 12.177 $\\pm$ 1.813 (c)  5.350 $\\pm$ 1.205 (b)
## 5             * 78.253 $\\pm$ 4.859 (b) 83.484 $\\pm$ 5.052 (c)
## 6             *  0.869 $\\pm$ 0.221 (b)  0.623 $\\pm$ 0.189 (a)
##                        PM                     EMC                      ET
## 1 27.711 $\\pm$ 0.698 (a) 28.193 $\\pm$ 0.660 (b) 28.243 $\\pm$ 1.140 (b)
## 2 30.252 $\\pm$ 0.558 (a) 32.603 $\\pm$ 2.633 (b) 32.676 $\\pm$ 3.550 (b)
## 3 25.698 $\\pm$ 1.255 (c) 25.364 $\\pm$ 1.099 (b) 25.391 $\\pm$ 1.366 (b)
## 4  4.554 $\\pm$ 1.221 (a)  7.239 $\\pm$ 3.429 (a)  7.285 $\\pm$ 4.144 (a)
## 5 75.689 $\\pm$ 3.709 (a) 77.090 $\\pm$ 3.199 (a) 78.329 $\\pm$ 5.436 (b)
## 6  0.909 $\\pm$ 0.162 (c)  0.877 $\\pm$ 0.131 (b)  0.842 $\\pm$ 0.235 (b)
##                       FEC
## 1 27.869 $\\pm$ 1.410 (a)
## 2 31.447 $\\pm$ 2.609 (a)
## 3 23.693 $\\pm$ 1.360 (a)
## 4  7.754 $\\pm$ 3.352 (b)
## 5 84.873 $\\pm$ 5.951 (c)
## 6  0.563 $\\pm$ 0.222 (a)

5.1 Saída em LaTeX (copiar/colar)

cat("\\n% --- Tabela LaTeX (copie a partir daqui) ---\\n")

% — Tabela LaTeX (copie a partir daqui) —

kable(tabela_final,
      format = "latex",
      booktabs = TRUE,
      escape = FALSE,
      caption = "Médias $\\pm$ desvios (com letras do Tukey) e significâncias da ANAVA (ns, *, **, ***).") %>%
  kable_styling(latex_options = c("hold_position", "scale_down")) %>%
  print()
cat("\\n% --- fim da tabela ---\\n")

% — fim da tabela —

# Se o output for HTML, mostra tabela HTML.
# Se for LaTeX/PDF, mostra tabela LaTeX.
fmt <- if (knitr::is_latex_output()) "latex" else "html"

tab <- knitr::kable(
  tabela_final,
  format = fmt,
  booktabs = TRUE,
  escape = FALSE,
  caption = "Médias $\\pm$ desvios (com letras do Tukey) e significâncias da ANAVA (ns, *, **, ***)."
)

if (fmt == "latex") {
  tab <- kableExtra::kable_styling(tab, latex_options = c("hold_position", "scale_down"))
} else {
  tab <- kableExtra::kable_styling(tab, full_width = FALSE)
}

tab
Médias \(\pm\) desvios (com letras do Tukey) e significâncias da ANAVA (ns, , , ).
var sig_Ambiente sig_Estacao sig_Interacao AD FL PM EMC ET FEC
Temperatura.média.do.ar…C. *** *** *** 28.730 \(\pm\) 1.047 (c) 28.003 \(\pm\) 1.093 (b) 27.711 \(\pm\) 0.698 (a) 28.193 \(\pm\) 0.660 (b) 28.243 \(\pm\) 1.140 (b) 27.869 \(\pm\) 1.410 (a)
Temperatura.máxima.do.ar…C. *** *** *** 36.347 \(\pm\) 1.630 (b) 30.605 \(\pm\) 1.298 (a) 30.252 \(\pm\) 0.558 (a) 32.603 \(\pm\) 2.633 (b) 32.676 \(\pm\) 3.550 (b) 31.447 \(\pm\) 2.609 (a)
Temperatura.mínima.do.ar…C. *** *** ns 24.170 \(\pm\) 1.417 (a) 25.255 \(\pm\) 1.159 (b) 25.698 \(\pm\) 1.255 (c) 25.364 \(\pm\) 1.099 (b) 25.391 \(\pm\) 1.366 (b) 23.693 \(\pm\) 1.360 (a)
Amplitude.térmica.do.ar…C. *** ** *** 12.177 \(\pm\) 1.813 (c) 5.350 \(\pm\) 1.205 (b) 4.554 \(\pm\) 1.221 (a) 7.239 \(\pm\) 3.429 (a) 7.285 \(\pm\) 4.144 (a) 7.754 \(\pm\) 3.352 (b)
UH…. *** ***
78.253 \(\pm\) 4.859 (b) 83.484 \(\pm\) 5.052 (c) 75.689 \(\pm\) 3.709 (a) 77.090 \(\pm\) 3.199 (a) 78.329 \(\pm\) 5.436 (b) 84.873 \(\pm\) 5.951 (c)
Déficit.de.pressão.de.vapor.de.água..kPa. *** ***
0.869 \(\pm\) 0.221 (b) 0.623 \(\pm\) 0.189 (a) 0.909 \(\pm\) 0.162 (c) 0.877 \(\pm\) 0.131 (b) 0.842 \(\pm\) 0.235 (b) 0.563 \(\pm\) 0.222 (a)
# Converte p-valor em símbolos (ns, *, **, ***)
p_to_sig <- function(p){
  if (is.na(p)) return(NA_character_)
  if (p < 0.001) return("***")
  if (p < 0.01)  return("**")
  if (p < 0.05)  return("*")
  return("ns")
}

# Formata tabela de ANOVA de um objeto aov()
anova_table <- function(fit){
  an <- anova(fit)

  # Monta data.frame com colunas essenciais
  out <- data.frame(
    Fonte = rownames(an),
    GL    = an[["Df"]],
    F     = an[["F value"]],
    p     = an[["Pr(>F)"]],
    stringsAsFactors = FALSE
  )

  # Remove linha de resíduos se quiser (opcional)
  # out <- out[out$Fonte != "Residuals", ]

  out$sig <- vapply(out$p, p_to_sig, character(1))

  # Formata números (sem destruir NA)
  out$F <- ifelse(is.na(out$F), NA, sprintf("%.3f", out$F))
  out$p <- ifelse(is.na(out$p), NA, sprintf("%.4f", out$p))

  out
}
fmt <- if (knitr::is_latex_output()) "latex" else "html"

for (v in resp_vars){

  form <- as.formula(paste0("`", v, "` ~ `Ambiente` * `Estação`"))
  fit  <- aov(form, data = dados_2)

  tabA <- anova_table(fit)

  cat("\n\n")
  cat("## ", v, "\n\n", sep="")

  k <- knitr::kable(
    tabA,
    format = fmt,
    booktabs = TRUE,
    escape = FALSE,
    caption = paste0("ANOVA para: ", v, " (modelo: ", v, " ~ Ambiente * Estação)")
  )

  if (fmt == "latex") {
    k <- kableExtra::kable_styling(k, latex_options = c("hold_position", "scale_down"))
  } else {
    k <- kableExtra::kable_styling(k, full_width = FALSE)
  }

  print(k)
}

5.2 Temperatura.média.do.ar…C.

ANOVA para: Temperatura.média.do.ar…C. (modelo: Temperatura.média.do.ar…C. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 65.139 0.0000 ***
Estação 2 7.091 0.0009 ***
Ambiente:Estação 4 49.509 0.0000 ***
Residuals 441 NA NA NA

5.3 Temperatura.máxima.do.ar…C.

ANOVA para: Temperatura.máxima.do.ar…C. (modelo: Temperatura.máxima.do.ar…C. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 1644.939 0.0000 ***
Estação 2 48.214 0.0000 ***
Ambiente:Estação 4 27.972 0.0000 ***
Residuals 441 NA NA NA

5.4 Temperatura.mínima.do.ar…C.

ANOVA para: Temperatura.mínima.do.ar…C. (modelo: Temperatura.mínima.do.ar…C. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 77.509 0.0000 ***
Estação 2 85.459 0.0000 ***
Ambiente:Estação 4 0.494 0.7398 ns
Residuals 441 NA NA NA

5.5 Amplitude.térmica.do.ar…C.

ANOVA para: Amplitude.térmica.do.ar…C. (modelo: Amplitude.térmica.do.ar…C. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 1447.671 0.0000 ***
Estação 2 4.833 0.0084 **
Ambiente:Estação 4 14.854 0.0000 ***
Residuals 441 NA NA NA

5.6 UH….

ANOVA para: UH…. (modelo: UH…. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 193.538 0.0000 ***
Estação 2 156.656 0.0000 ***
Ambiente:Estação 4 2.929 0.0207
Residuals 441 NA NA NA

5.7 Déficit.de.pressão.de.vapor.de.água..kPa.

ANOVA para: Déficit.de.pressão.de.vapor.de.água..kPa. (modelo: Déficit.de.pressão.de.vapor.de.água..kPa. ~ Ambiente * Estação)
Fonte GL F p sig
Ambiente 2 159.637 0.0000 ***
Estação 2 142.813 0.0000 ***
Ambiente:Estação 4 2.434 0.0467
Residuals 441 NA NA NA

6 Tabela estilo artigo (Estação x Ambiente)

A tabela abaixo segue o mesmo formato do exemplo (média ± desvio padrão por ambiente dentro de cada estação, letras do Tukey para comparar ambientes dentro da estação, e F/GL do teste Ambiente dentro da estação).

library(dplyr)
library(tidyr)
library(emmeans)
library(multcomp)
library(multcompView)
library(knitr)
library(kableExtra)

# Função para extrair letras do Tukey (ajuste Tukey) em um aov simples
tukey_letters_1f <- function(fit, fac="Ambiente"){
  emm <- emmeans::emmeans(fit, specs = fac)
  cld_df <- as.data.frame(multcomp::cld(emm, Letters = letters, adjust = "tukey"))
  cld_df$.group <- gsub("\\s+", "", cld_df$.group)
  cld_df[, c(fac, ".group"), drop=FALSE]
}

# P-valor -> símbolo
p_to_sig <- function(p){
  if (is.na(p)) return("")
  if (p < 0.001) return("***")
  if (p < 0.01)  return("**")
  if (p < 0.05)  return("*")
  return("ns")
}

fmt_media <- function(m, s, digits=2){
  sprintf(paste0("%.",digits,"f \\\\pm %.",digits,"f"), m, s)
}

fmt_F <- function(Fv, p){
  if (is.na(Fv)) return("")
  paste0(sprintf("%.2f", Fv), p_to_sig(p))
}

# Para cada variável resposta, monta uma tabela no padrão do exemplo
for(v in resp_vars){

  # data.frame com resultados por estação
  out_list <- list()

  for(est in levels(dados_2$Estação)){
    df_est <- dados_2 %>% filter(Estação == est)

    # ANOVA simples dentro da estação: y ~ Ambiente
    form_est <- as.formula(paste0("`", v, "` ~ `Ambiente`"))
    fit_est  <- aov(form_est, data = df_est)
    an       <- anova(fit_est)

    # pega F e p do efeito Ambiente; GL residual para a coluna GL do exemplo
    # (no exemplo, GL é do resíduo)
    Fv <- tryCatch(an[["F value"]][1], error=function(e) NA_real_)
    pv <- tryCatch(an[["Pr(>F)"]][1], error=function(e) NA_real_)
    gl_res <- tryCatch(an[["Df"]][2], error=function(e) NA_real_)

    # médias ± sd por ambiente
    ms <- df_est %>%
      group_by(Ambiente) %>%
      summarise(media = mean(.data[[v]], na.rm=TRUE),
                desvio = sd(.data[[v]], na.rm=TRUE),
                .groups="drop")

    # letras Tukey por ambiente (dentro da estação)
    letras <- tukey_letters_1f(fit_est, "Ambiente")

    tab <- ms %>%
      left_join(letras, by="Ambiente") %>%
      mutate(val = paste0(fmt_media(media, desvio, digits=2), " ", .group))

    # garante colunas para todos os níveis de Ambiente (ex.: PM, AD)
    tab_w <- tab %>%
      dplyr::select(Ambiente, val) %>%
      tidyr::pivot_wider(names_from = Ambiente, values_from = val)

    tab_w <- tab_w %>%
      mutate(Estação = est,
             GL = gl_res,
             F  = fmt_F(Fv, pv)) %>%
      dplyr::select(Estação, everything(), GL, F)

    out_list[[est]] <- tab_w
  }

  out <- bind_rows(out_list)

  # Ordena pelas estações na ordem do fator
  out$Estação <- factor(out$Estação, levels = levels(dados_2$Estação))
  out <- out %>% dplyr::arrange(Estação)

  cat("\n\n## ", v, "\n\n", sep="")

  k <- knitr::kable(
    out,
    format = if (knitr::is_latex_output()) "latex" else "html",
    booktabs = TRUE,
    escape = FALSE,
    align = "l",
    caption = paste0("Média ± DP por ambiente dentro de cada estação para: ", v,
                     ". Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.")
  )

  if (knitr::is_latex_output()) {
    k <- kableExtra::kable_styling(k, latex_options = c("hold_position", "scale_down"))
  } else {
    k <- kableExtra::kable_styling(k, full_width = FALSE)
  }

  print(k)
}

6.1 Temperatura.média.do.ar…C.

Média ± DP por ambiente dentro de cada estação para: Temperatura.média.do.ar…C.. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 28.87 \pm 0.36 b 27.92 \pm 0.68 a 27.79 \pm 0.17 a 177 99.27***
ET 29.24 \pm 1.03 c 27.53 \pm 0.86 a 27.96 \pm 0.73 b 177 60.40***
FEC 27.45 \pm 0.97 a 29.12 \pm 1.39 b 27.04 \pm 0.86 a 87 30.18***

6.2 Temperatura.máxima.do.ar…C.

Média ± DP por ambiente dentro de cada estação para: Temperatura.máxima.do.ar…C.. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 36.11 \pm 0.80 c 31.45 \pm 0.89 b 30.25 \pm 0.30 a 177 1125.55***
ET 37.30 \pm 1.89 b 30.47 \pm 1.20 a 30.27 \pm 0.79 a 177 511.86***
FEC 34.92 \pm 0.99 c 29.20 \pm 0.72 a 30.23 \pm 0.39 b 87 507.53***

6.3 Temperatura.mínima.do.ar…C.

Média ± DP por ambiente dentro de cada estação para: Temperatura.mínima.do.ar…C.. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 24.40 \pm 1.15 a 25.64 \pm 0.69 b 26.06 \pm 0.61 c 177 61.65***
ET 24.61 \pm 1.36 a 25.50 \pm 1.16 b 26.06 \pm 1.17 c 177 20.83***
FEC 22.82 \pm 1.21 a 23.99 \pm 1.06 b 24.26 \pm 1.37 b 87 11.85***

6.4 Amplitude.térmica.do.ar…C.

Média ± DP por ambiente dentro de cada estação para: Amplitude.térmica.do.ar…C.. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 11.71 \pm 1.40 c 5.81 \pm 1.18 b 4.19 \pm 0.69 a 177 732.78***
ET 12.68 \pm 2.18 c 4.96 \pm 1.20 b 4.21 \pm 1.06 a 177 539.82***
FEC 12.10 \pm 1.48 b 5.20 \pm 0.95 a 5.96 \pm 1.35 a 87 261.45***

6.5 UH….

Média ± DP por ambiente dentro de cada estação para: UH….. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 76.27 \pm 1.93 b 80.75 \pm 1.57 c 74.25 \pm 1.51 a 177 235.11***
ET 77.36 \pm 4.77 b 82.73 \pm 4.57 c 74.89 \pm 3.64 a 177 50.82***
FEC 84.01 \pm 4.83 b 90.44 \pm 4.11 c 80.17 \pm 3.56 a 87 45.88***

6.6 Déficit.de.pressão.de.vapor.de.água..kPa.

Média ± DP por ambiente dentro de cada estação para: Déficit.de.pressão.de.vapor.de.água..kPa.. Letras do Tukey comparam ambientes dentro da estação; F e GL referem-se ao teste do fator Ambiente dentro da estação.
Estação AD FL PM GL F
EMC 0.94 \pm 0.09 b 0.72 \pm 0.06 a 0.96 \pm 0.06 b 177 197.66***
ET 0.93 \pm 0.22 b 0.64 \pm 0.18 a 0.95 \pm 0.16 b 177 50.07***
FEC 0.59 \pm 0.20 b 0.38 \pm 0.16 a 0.71 \pm 0.16 c 87 28.09***