0.1 Instrumentos de medida

As medidas de referência foram obtidas utilizando dispositivos eletrônicos comerciais destinados ao monitoramento domiciliar de parâmetros fisiológicos, metabólicos e antropométricos. A pressão arterial sistólica (PAS), pressão arterial diastólica (PAD) e frequência cardíaca (FC) foram medidas por meio de um monitor automático de braço Omron HEM-7346T (Omron Healthcare Co., Kyoto, Japão), equipado com tecnologia Bluetooth para armazenamento e transferência dos dados.

A massa corporal total (MCT) e a composição corporal foram obtidas utilizando uma balança de bioimpedância Omron HBF-222T (Omron Healthcare Co., Kyoto, Japão). A temperatura corporal foi medida com um termômetro digital G-Tech TH-186 (Accumed-Glicomed, Duque de Caxias, RJ, Brasil). A saturação periférica de oxigênio (SpO₂) e a frequência cardíaca também foram avaliadas por um oxímetro de pulso de dedo Multilaser Saúde HC261 (Multilaser Industrial S.A., Extrema, MG, Brasil).

A glicose intersticial foi monitorada continuamente por meio do sistema FreeStyle Libre (Abbott Diabetes Care Inc., Alameda, CA, EUA), um sensor de monitorização contínua da glicose (CGM) aplicado na região posterior do braço, capaz de registrar automaticamente as concentrações de glicose ao longo do dia sem necessidade de punções digitais rotineiras.

As medidas obtidas pelos dispositivos de referência foram comparadas às fornecidas por dispositivos vestíveis da Samsung Electronics Co. (Suwon, Coreia do Sul), incluindo smartwatch Galaxy Watch e pulseira Galaxy Fit. As variáveis avaliadas compreenderam frequência cardíaca, saturação periférica de oxigênio, massa corporal total, percentual de gordura corporal e demais parâmetros fisiológicos disponibilizados pelos dispositivos.

Todos os equipamentos foram utilizados de acordo com as instruções dos fabricantes. As medições foram realizadas em ambiente domiciliar durante o período de acompanhamento longitudinal do participante. Os dispositivos Omron, G-Tech, Multilaser e FreeStyle Libre foram considerados métodos de referência para fins de comparação e avaliação de equivalência metrológica dos dispositivos vestíveis.

A equivalência entre os métodos foi investigada por meio da abordagem estrutural implementada no pacote eirasAgree, baseada na avaliação sequencial de viés estrutural, precisão estrutural e concordância estrutural.

1 Objetivo

Analisar as variáveis digitais:

Temperatura, SpO2_WTC, SpO2_ML, PI_ML, FC_ML, FC_WTC, FC_Gfit, FR_Gfit, Glicemia, MCT_ML, GorduraCorp_WTC.

A análise usa apenas a janela temporal em que há pelo menos uma variável digital observada.

As comparações de equivalência de métodos são feitas diretamente com eirasagree::AllStructuralTests(), sem reimplementar o método:

As demais variáveis digitais são analisadas por descrição, gráficos temporais e associação com FC, MCT e gordura corporal da balança.

2 Funções

load_pkgs <- function(pkgs) {
  for (p in pkgs) {
    if (!requireNamespace(p, quietly = TRUE)) {
      stop("Pacote ausente: ", p, ". Instale com install.packages('", p, "') ou conforme documentação do pacote.")
    }
    suppressPackageStartupMessages(library(p, character.only = TRUE))
  }
  invisible(TRUE)
}

safe_locale_ptbr <- function() {
  suppressWarnings(try(Sys.setlocale("LC_ALL", "pt_BR.UTF-8"), silent = TRUE))
  invisible(TRUE)
}

as_num <- function(x) {
  suppressWarnings(as.numeric(x))
}

stop_if_missing <- function(df, vars) {
  miss <- setdiff(vars, names(df))
  if (length(miss) > 0) stop("Colunas ausentes: ", paste(miss, collapse = ", "))
  invisible(TRUE)
}

date_range_str <- function(d) {
  d <- as.Date(d)
  d <- d[is.finite(d)]
  if (length(d) == 0) return(NA_character_)
  paste0("Início: ", format(min(d), "%Y-%m-%d"), "  Fim: ", format(max(d), "%Y-%m-%d"))
}

axis_month_year <- function(dates, by = "1 month") {
  dates <- as.Date(dates)
  dates <- dates[is.finite(dates)]
  if (length(dates) == 0) return(invisible(NULL))
  at <- seq(from = as.Date(cut(min(dates), "month")),
            to   = as.Date(cut(max(dates), "month")),
            by   = by)
  axis(1, at = at, labels = format(at, "%m/%y"), las = 2, cex.axis = 0.8)
  invisible(at)
}

plot_calendar_var <- function(df, date_col, y_col, main = NULL, ylab = NULL,
                              by = "1 month", hlines = NULL, show_smooth = TRUE) {
  stop_if_missing(df, c(date_col, y_col))
  d <- as.Date(df[[date_col]])
  y <- as_num(df[[y_col]])
  ok <- is.finite(d) & is.finite(y)
  d <- d[ok]
  y <- y[ok]
  if (length(y) < 1) {
    plot.new()
    title(main = paste0(y_col, ": sem dados"))
    return(invisible(NULL))
  }
  o <- order(d)
  d <- d[o]
  y <- y[o]
  if (is.null(main)) main <- paste0("Paciente: JOS | ", y_col)
  if (is.null(ylab)) ylab <- y_col
  yl <- range(y, na.rm = TRUE)
  if (diff(yl) == 0) yl <- yl + c(-1, 1)
  plot(d, y, type = "p", cex = 0.55, xaxt = "n", xlim = range(d), ylim = yl,
       main = main, xlab = "Mês/Ano", ylab = ylab, col = "black")
  lines(d, y, col = "gray")
  axis_month_year(d, by = by)
  if (!is.null(hlines)) {
    for (h in hlines) abline(h = h, lty = 2)
  }
  if (show_smooth && length(y) >= 10) {
    x <- seq_along(y)
    bw <- suppressWarnings(KernSmooth::dpill(x, y, gridsize = length(y)))
    if (!is.finite(bw) || bw <= 0) bw <- max(1, length(y) / 20)
    lp <- KernSmooth::locpoly(x, y, bandwidth = bw, gridsize = length(y))
    sm <- stats::approx(lp$x, lp$y, xout = x, rule = 2)$y
    lines(d, sm, lwd = 1.5)
  }
  invisible(data.frame(Data = d, y = y))
}


round_numeric <- function(df, digits = 4) {
  out <- as.data.frame(df)
  num <- vapply(out, is.numeric, logical(1))
  out[num] <- lapply(out[num], round, digits = digits)
  out
}

summary_numeric <- function(df, vars) {
  out <- data.frame(
    variavel = character(0),
    n = integer(0),
    media = numeric(0),
    dp = numeric(0),
    mediana = numeric(0),
    q1 = numeric(0),
    q3 = numeric(0),
    minimo = numeric(0),
    maximo = numeric(0)
  )
  for (v in vars) {
    y <- as_num(df[[v]])
    y <- y[is.finite(y)]
    if (length(y) == 0) {
      linha <- data.frame(variavel = v, n = 0, media = NA, dp = NA, mediana = NA,
                          q1 = NA, q3 = NA, minimo = NA, maximo = NA)
    } else {
      linha <- data.frame(
        variavel = v,
        n = length(y),
        media = mean(y),
        dp = stats::sd(y),
        mediana = stats::median(y),
        q1 = as.numeric(stats::quantile(y, 0.25, na.rm = TRUE)),
        q3 = as.numeric(stats::quantile(y, 0.75, na.rm = TRUE)),
        minimo = min(y),
        maximo = max(y)
      )
    }
    out <- rbind(out, linha)
  }
  out
}

cor_pair_table <- function(df, y_vars, x_vars) {
  out <- data.frame(
    y = character(0),
    x = character(0),
    n = integer(0),
    pearson = numeric(0),
    spearman = numeric(0),
    p_pearson = numeric(0),
    p_spearman = numeric(0)
  )
  for (yv in y_vars) {
    for (xv in x_vars) {
      y <- as_num(df[[yv]])
      x <- as_num(df[[xv]])
      ok <- is.finite(x) & is.finite(y)
      n <- sum(ok)
      if (n >= 4) {
        ct1 <- suppressWarnings(stats::cor.test(x[ok], y[ok], method = "pearson"))
        ct2 <- suppressWarnings(stats::cor.test(x[ok], y[ok], method = "spearman", exact = FALSE))
        linha <- data.frame(y = yv, x = xv, n = n,
                            pearson = unname(ct1$estimate),
                            spearman = unname(ct2$estimate),
                            p_pearson = ct1$p.value,
                            p_spearman = ct2$p.value)
      } else {
        linha <- data.frame(y = yv, x = xv, n = n,
                            pearson = NA, spearman = NA,
                            p_pearson = NA, p_spearman = NA)
      }
      out <- rbind(out, linha)
    }
  }
  out
}

scatter_ref <- function(df, y_col, x_col, main = NULL) {
  y <- as_num(df[[y_col]])
  x <- as_num(df[[x_col]])
  ok <- is.finite(x) & is.finite(y)
  if (sum(ok) < 3) {
    plot.new()
    title(main = paste0(y_col, " vs ", x_col, ": dados insuficientes"))
    return(invisible(NULL))
  }
  if (is.null(main)) main <- paste0(y_col, " vs ", x_col)
  plot(x[ok], y[ok], pch = 1, cex = 0.65, col = "black",
       xlab = x_col, ylab = y_col, main = main)
  abline(stats::lm(y[ok] ~ x[ok]), lty = 1)
  invisible(TRUE)
}

make_eiras_data <- function(df, reference_col, newmethod_col) {
  stop_if_missing(df, c(reference_col, newmethod_col))
  x <- as_num(df[[reference_col]])
  y <- as_num(df[[newmethod_col]])
  ok <- is.finite(x) & is.finite(y)
  out <- data.frame(Referencia = x[ok], NovoMetodo = y[ok])
  ## Nomes simples evitam erro de arquivos gerados pelo eirasagree
  ## com caracteres especiais, como %, parênteses e acentos.
  out
}

safe_file_label <- function(x) {
  x <- iconv(x, from = "", to = "ASCII//TRANSLIT")
  x <- gsub("[^A-Za-z0-9]+", "_", x)
  x <- gsub("^_+|_+$", "", x)
  x
}

run_eirasagree_pair <- function(df, reference_col, newmethod_col,
                                alpha = 0.05, out.format = "html") {
  dat <- make_eiras_data(df, reference_col, newmethod_col)

  cat("\n\nComparação estrutural: ", newmethod_col, " vs ", reference_col, "  \n", sep = "")
  cat("n pares completos: ", nrow(dat), "  \n", sep = "")

  if (nrow(dat) < 5) {
    cat("Dados insuficientes para comparação estrutural.\n")
    return(invisible(NULL))
  }

  subdir <- paste0(safe_file_label(newmethod_col), "_vs_", safe_file_label(reference_col))
  outdir <- file.path("eirasagree_outputs", subdir)
  dir.create(outdir, recursive = TRUE, showWarnings = FALSE)

  oldwd <- getwd()
  setwd(outdir)

  zz <- file("console_eirasagree.txt", open = "wt")
  sink(zz)
  sink(zz, type = "message")

  out <- NULL
  erro <- NULL

  tryCatch(
    {
      out <- eirasagree::AllStructuralTests(
        dat,
        reference.cols = 1,
        newmethod.cols = 2,
        alpha = alpha,
        out.format = out.format
      )
    },
    error = function(e) {
      erro <<- e
    }
  )

  sink(type = "message")
  sink()
  close(zz)
  setwd(oldwd)

  if (!is.null(erro)) {
    stop("Erro em eirasagree::AllStructuralTests para ",
         newmethod_col, " vs ", reference_col, ": ", conditionMessage(erro))
  }

  html_file <- file.path(outdir, "Referencia_and_NovoMetodo.html")
  console_file <- file.path(outdir, "console_eirasagree.txt")

  if (file.exists(html_file)) {
    cat("Relatório HTML: [abrir resultado](", html_file, ")  \n", sep = "")
  } else {
    cat("Relatório HTML não localizado. Ver console: [console_eirasagree.txt](", console_file, ")  \n", sep = "")
  }

  invisible(out)
}

3 Leitura e janela temporal digital

pkgs <- c("readxl", "dplyr", "knitr", "KernSmooth", "GGally", "eirasagree")
load_pkgs(pkgs)
safe_locale_ptbr()

df0 <- readxl::read_excel(params$xlsx_path, sheet = params$sheet_pressoes)

vars_digitais <- c(
  "Temperatura",
  "SpO2_WTC",
  "SpO2_ML",
  "PI_ML",
  "FC_ML",
  "FC_WTC",
  "FC_Gfit",
  "FR_Gfit",
  "Glicemia",
  "MCT_ML",
  "GorduraCorp_WTC"
)

vars_referencia <- c(
  "Pulso(bpm)",
  "Peso(kg)",
  "Gordura corporal(%)"
)

stop_if_missing(df0, c("Data da medição", vars_digitais, vars_referencia))

df <- as.data.frame(df0)
df[["Data da medição"]] <- as.POSIXct(df[["Data da medição"]], tz = "America/Sao_Paulo")

for (v in c(vars_digitais, vars_referencia)) {
  df[[v]] <- as_num(df[[v]])
}

linhas_digitais <- rowSums(!is.na(df[, vars_digitais, drop = FALSE])) > 0
df_digital <- df[linhas_digitais, , drop = FALSE]
df_digital <- df_digital[order(df_digital[["Data da medição"]]), , drop = FALSE]

cat("Janela digital | ", date_range_str(df_digital[["Data da medição"]]), "\n")
## Janela digital |  Início: 2023-10-22  Fim: 2024-02-01
cat("n linhas na janela digital:", nrow(df_digital), "\n")
## n linhas na janela digital: 98

4 Resumo descritivo

resumo <- summary_numeric(df_digital, c(vars_digitais, vars_referencia))
knitr::kable(round_numeric(resumo, 4), caption = "Resumo descritivo na janela temporal digital")
Resumo descritivo na janela temporal digital
variavel n media dp mediana q1 q3 minimo maximo
Temperatura 98 35.6143 0.2577 35.60 35.400 35.800 34.9 36.2
SpO2_WTC 86 93.7674 2.5607 94.00 92.000 95.750 90.0 100.0
SpO2_ML 90 96.4778 1.2382 96.00 96.000 98.000 94.0 99.0
PI_ML 90 1009.1678 6690.4728 6.35 4.600 7.900 1.3 45142.0
FC_ML 90 78.3111 5.9806 78.00 74.000 82.750 66.0 94.0
FC_WTC 89 83.0449 6.8853 82.00 79.000 87.000 70.0 101.0
FC_Gfit 85 79.8118 6.8112 80.00 75.000 85.000 64.0 99.0
FR_Gfit 86 16.1977 1.6579 16.00 15.000 17.000 13.0 20.0
Glicemia 28 99.5000 5.7252 99.50 94.750 102.750 89.0 113.0
MCT_ML 81 85.7370 0.6972 85.70 85.300 86.200 83.6 87.3
GorduraCorp_WTC 79 29.0114 0.8419 29.10 28.700 29.600 26.1 30.5
Pulso(bpm) 98 80.5612 7.4930 81.00 74.000 85.000 68.0 105.0
Peso(kg) 98 85.2429 0.7355 85.20 84.800 85.675 83.3 87.1
Gordura corporal(%) 98 28.8194 0.3366 28.90 28.625 29.075 28.0 29.6

5 Gráficos temporais na janela efetiva de cada variável

Cada gráfico usa apenas as datas em que a própria variável tem valor observado. Isso evita eixo temporal artificialmente longo.

for (v in vars_digitais) {
  plot_calendar_var(
    df = df_digital,
    date_col = "Data da medição",
    y_col = v,
    main = paste0("Paciente: JOS | ", v),
    ylab = v,
    by = "1 month"
  )
}

6 Correlações com FC, MCT e gordura corporal da balança

cor_tab <- cor_pair_table(
  df = df_digital,
  y_vars = vars_digitais,
  x_vars = vars_referencia
)
knitr::kable(round_numeric(cor_tab, 4), caption = "Correlação das variáveis digitais com FC, MCT e gordura corporal da balança")
Correlação das variáveis digitais com FC, MCT e gordura corporal da balança
y x n pearson spearman p_pearson p_spearman
Temperatura Pulso(bpm) 98 0.3317 0.2898 0.0008 0.0038
Temperatura Peso(kg) 98 -0.2366 -0.2288 0.0190 0.0234
Temperatura Gordura corporal(%) 98 -0.2017 -0.2035 0.0464 0.0445
SpO2_WTC Pulso(bpm) 86 0.0192 0.0257 0.8609 0.8140
SpO2_WTC Peso(kg) 86 0.1835 0.2357 0.0908 0.0289
SpO2_WTC Gordura corporal(%) 86 0.0694 0.1532 0.5255 0.1591
SpO2_ML Pulso(bpm) 90 -0.3842 -0.3740 0.0002 0.0003
SpO2_ML Peso(kg) 90 0.2809 0.2762 0.0073 0.0084
SpO2_ML Gordura corporal(%) 90 0.2688 0.2774 0.0104 0.0081
PI_ML Pulso(bpm) 90 -0.0564 0.3502 0.5975 0.0007
PI_ML Peso(kg) 90 0.1827 -0.0084 0.0847 0.9377
PI_ML Gordura corporal(%) 90 0.1558 -0.0168 0.1424 0.8753
FC_ML Pulso(bpm) 90 0.7416 0.6960 0.0000 0.0000
FC_ML Peso(kg) 90 -0.2202 -0.1862 0.0371 0.0789
FC_ML Gordura corporal(%) 90 -0.2006 -0.1862 0.0580 0.0789
FC_WTC Pulso(bpm) 89 0.5301 0.5389 0.0000 0.0000
FC_WTC Peso(kg) 89 -0.0315 -0.0782 0.7696 0.4663
FC_WTC Gordura corporal(%) 89 -0.1016 -0.1226 0.3434 0.2525
FC_Gfit Pulso(bpm) 85 0.6742 0.6079 0.0000 0.0000
FC_Gfit Peso(kg) 85 -0.2624 -0.2525 0.0152 0.0198
FC_Gfit Gordura corporal(%) 85 -0.2621 -0.2581 0.0154 0.0171
FR_Gfit Pulso(bpm) 86 0.0891 0.0540 0.4144 0.6217
FR_Gfit Peso(kg) 86 -0.4480 -0.4280 0.0000 0.0000
FR_Gfit Gordura corporal(%) 86 -0.4230 -0.4448 0.0000 0.0000
Glicemia Pulso(bpm) 28 -0.0121 -0.0629 0.9514 0.7506
Glicemia Peso(kg) 28 0.1015 0.0967 0.6072 0.6245
Glicemia Gordura corporal(%) 28 0.1128 0.1147 0.5675 0.5610
MCT_ML Pulso(bpm) 81 -0.1836 -0.1485 0.1009 0.1858
MCT_ML Peso(kg) 81 0.8744 0.8827 0.0000 0.0000
MCT_ML Gordura corporal(%) 81 0.7882 0.7994 0.0000 0.0000
GorduraCorp_WTC Pulso(bpm) 79 -0.2953 -0.3261 0.0082 0.0034
GorduraCorp_WTC Peso(kg) 79 -0.0516 -0.0428 0.6514 0.7080
GorduraCorp_WTC Gordura corporal(%) 79 -0.0408 -0.0005 0.7214 0.9964

7 Matrizes de dispersão

vars_pair <- c(vars_digitais, vars_referencia)
vars_pair <- vars_pair[vars_pair %in% names(df_digital)]

ok_n <- sapply(vars_pair, function(v) sum(is.finite(as_num(df_digital[[v]]))))
vars_pair <- vars_pair[ok_n >= 3]

if (length(vars_pair) >= 2) {
  print(GGally::ggpairs(
    df_digital[, vars_pair, drop = FALSE],
    title = "Variáveis digitais e referências da balança",
    diag = list(continuous = "densityDiag")
  ))
}

8 Dispersões contra referências

for (v in vars_digitais) {
  scatter_ref(df_digital, y_col = v, x_col = "Pulso(bpm)")
  scatter_ref(df_digital, y_col = v, x_col = "Peso(kg)")
  scatter_ref(df_digital, y_col = v, x_col = "Gordura corporal(%)")
}

9 Comparação estrutural de métodos com eirasagree

Método aplicado diretamente por eirasagree::AllStructuralTests().

Apenas pares que medem o mesmo construto são submetidos à comparação estrutural:

9.1 FC_ML versus Pulso(bpm)

Comparação estrutural: FC_ML vs Pulso(bpm)
n pares completos: 90
Relatório HTML não localizado. Ver console: console_eirasagree.txt

9.2 FC_WTC versus Pulso(bpm)

Comparação estrutural: FC_WTC vs Pulso(bpm)
n pares completos: 89
Relatório HTML não localizado. Ver console: console_eirasagree.txt

9.3 FC_Gfit versus Pulso(bpm)

Comparação estrutural: FC_Gfit vs Pulso(bpm)
n pares completos: 85
Relatório HTML não localizado. Ver console: console_eirasagree.txt

9.4 SpO2_ML versus SpO2_WTC

Comparação estrutural: SpO2_ML vs SpO2_WTC
n pares completos: 86
Relatório HTML não localizado. Ver console: console_eirasagree.txt

9.5 MCT_ML versus Peso(kg)

Comparação estrutural: MCT_ML vs Peso(kg)
n pares completos: 81
Relatório HTML não localizado. Ver console: console_eirasagree.txt

9.6 GorduraCorp_WTC versus Gordura corporal(%)

Comparação estrutural: GorduraCorp_WTC vs Gordura corporal(%)
n pares completos: 79
Relatório HTML não localizado. Ver console: console_eirasagree.txt

10 Observações metodológicas

O procedimento clássico de Bland-Altman não foi usado como critério decisório. A equivalência entre métodos foi avaliada pelo procedimento estrutural do pacote eirasagree, com decomposição em acurácia, precisão e concordância com a bissetriz.

Para variáveis que não medem o mesmo construto da balança, como Temperatura, PI_ML, FR_Gfit e Glicemia, não há comparação de método contra FC, MCT ou gordura corporal. SpO2_WTC e SpO2_ML medem o mesmo construto e, por isso, foram comparadas por eirasagree::AllStructuralTests().

11 Resumo das análises de equivalência

A equivalência entre os dispositivos vestíveis e os respectivos métodos de referência foi avaliada utilizando a abordagem estrutural implementada no pacote eirasAgree. A análise foi conduzida em três níveis complementares: viés estrutural (acurácia), precisão estrutural e concordância estrutural.

A frequência cardíaca medida pelo Galaxy Fit apresentou ausência de viés estrutural, manutenção da precisão estrutural e concordância estrutural compatível com a reta identidade. Esse foi o único dispositivo que satisfez simultaneamente todos os critérios de equivalência.

A frequência cardíaca medida pelo oxímetro Multilaser apresentou viés estrutural negativo e perda de precisão estrutural em relação ao monitor Omron, embora a hipótese de concordância estrutural não tenha sido rejeitada.

A frequência cardíaca medida pelo Galaxy Watch apresentou viés estrutural positivo em relação ao monitor Omron. Apesar da manutenção da precisão estrutural e da concordância estrutural, a presença de viés impediu a demonstração de equivalência.

A estimativa de gordura corporal fornecida pelo Galaxy Watch apresentou viés estrutural positivo e perda de precisão estrutural em relação à balança Omron HBF-222T.

A massa corporal total medida pela balança Multilaser apresentou viés estrutural positivo em relação à balança Omron HBF-222T, embora a precisão estrutural tenha sido preservada.

A saturação periférica de oxigênio medida pelo Galaxy Watch apresentou viés estrutural positivo e perda de precisão estrutural em relação ao oxímetro Multilaser HC261.

12 Conclusões dos testes

Os resultados demonstraram que a frequência cardíaca obtida pelo Galaxy Fit foi a única variável que apresentou evidência simultânea de ausência de viés estrutural, manutenção da precisão estrutural e concordância estrutural com o método de referência.

Os demais dispositivos apresentaram evidência de viés estrutural, perda de precisão estrutural ou ambos. Embora a hipótese de concordância estrutural não tenha sido rejeitada em nenhuma das comparações, a presença de viés e/ou perda de precisão impede a caracterização de equivalência metrológica.

Esses resultados evidenciam que a concordância estrutural, isoladamente, não é suficiente para demonstrar equivalência entre métodos de medida. A equivalência requer simultaneamente ausência de viés estrutural, manutenção da precisão estrutural e compatibilidade com a reta identidade.

13 Tabela-resumo dos resultados

Variável Método novo Método de referência Diferença média (Novo − Referência) IC95% do viés Viés estrutural Precisão estrutural Concordância estrutural
Frequência cardíaca (bpm) Galaxy Fit Omron HEM-7346T -0,46 -1,77 a 0,77 Não rejeitado Não rejeitada Não rejeitada
Frequência cardíaca (bpm) Oxímetro Multilaser HC261 Omron HEM-7346T -2,00 -2,92 a -1,08 Rejeitado Rejeitada Não rejeitada
Frequência cardíaca (bpm) Galaxy Watch Omron HEM-7346T +2,75 1,36 a 4,11 Rejeitado Não rejeitada Não rejeitada
Gordura corporal (%) Galaxy Watch Omron HBF-222T +0,26 0,03 a 0,46 Rejeitado Rejeitada Não rejeitada
Massa corporal total (kg) Balança Multilaser Omron HBF-222T +0,60 0,52 a 0,68 Rejeitado Não rejeitada Não rejeitada
Saturação periférica de oxigênio (%) Galaxy Watch Oxímetro Multilaser HC261 +2,74 2,43 a 3,05 Rejeitado Rejeitada Não rejeitada

14 Síntese dos resultados

Dos seis testes realizados, apenas um apresentou ausência de viés estrutural. Três comparações apresentaram simultaneamente viés estrutural e perda de precisão estrutural. Em todas as comparações a hipótese de concordância estrutural foi mantida. Entretanto, somente a frequência cardíaca medida pelo Galaxy Fit apresentou evidência compatível com equivalência metrológica completa em relação ao método de referência.