了解 Glubort() 在创建置信区间时处理逻辑向量与字符向量

Understanding Glubort() handling of logical vector vs character vector in creating confidence interval

我正在使用自定义样式函数来限制比值比和置信区间(如果它们低于或高于某个数值)以便于在最终 table 中打印。我的数据集中的所有变量都有效,除了一个,据我所知,它的组成不是唯一的。

library(tidyverse)
library(gtsummary)

bounded_style_ratio <- function(x, min = -Inf, max = Inf, ...) {
    dplyr::case_when(
        x < min ~ paste0("<", gtsummary::style_ratio(min, ...)),
        x > max ~ paste0(">", gtsummary::style_ratio(max, ...)),
        is.na(x) == TRUE ~ NA_character_,
        TRUE ~ gtsummary::style_ratio(x, ...)
    )
}
dat_2 <- structure(list(con = structure(c(1L, 1L, 1L, 2L, 1L, 2L, 1L, 
                                          1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 
                                          1L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 
                                          1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 
                                          1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 
                                          1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 
                                          1L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 
                                          1L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 
                                          1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 
                                          2L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 
                                          1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
                                          2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 
                                          2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                          1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 
                                          1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
                                          2L, 1L, 1L), .Label = c("0", "1"), class = "factor"), education_c = structure(c(2L, 
                                                                                                                          5L, 5L, 3L, 4L, 4L, 4L, 2L, 3L, 5L, 3L, 3L, 4L, 3L, 4L, 4L, 3L, 
                                                                                                                          4L, 2L, 5L, 4L, 3L, 3L, 5L, 5L, 4L, 3L, 2L, 1L, 5L, 5L, 5L, 2L, 
                                                                                                                          2L, 4L, 4L, 5L, 3L, 5L, 3L, 4L, 5L, 5L, 3L, 5L, 3L, 4L, 3L, 5L, 
                                                                                                                          5L, 5L, 4L, 3L, 5L, 5L, 4L, 2L, 5L, 3L, 4L, 3L, 4L, 4L, 5L, 4L, 
                                                                                                                          5L, 3L, 4L, 3L, 5L, 5L, 4L, 2L, 5L, 4L, 2L, 5L, 5L, 4L, 3L, 4L, 
                                                                                                                          4L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 3L, 3L, 5L, 4L, 2L, 2L, 5L, 4L, 
                                                                                                                          5L, 4L, 3L, 5L, 4L, 2L, 4L, 3L, 4L, 5L, 4L, 2L, 3L, 5L, 5L, 2L, 
                                                                                                                          5L, 3L, 4L, 3L, 4L, 3L, 2L, 4L, 2L, 5L, 3L, 5L, 5L, 3L, 5L, 5L, 
                                                                                                                          5L, 3L, 3L, 3L, 5L, 5L, 3L, 4L, 3L, 4L, 3L, 3L, 4L, 5L, 3L, 2L, 
                                                                                                                          5L, 2L, 3L, 3L, 4L, 5L, 5L, 4L, 4L, 3L, 4L, 4L, 5L, 4L, 4L, 5L, 
                                                                                                                          3L, 5L, 4L, 4L, 5L, 4L, 3L, 5L, 2L, 5L, 4L, 5L, 4L, 4L, 4L, 4L, 
                                                                                                                          3L, 4L, 5L, 3L, 4L, 5L, 3L, 4L, 4L, 4L, 4L, 4L, 5L, 4L, 4L, 4L, 
                                                                                                                          3L, 4L, 5L, 5L, 4L, 4L, 4L, 4L, 5L, 4L, 3L, 2L, 3L, 4L, 5L, 4L, 
                                                                                                                          5L, 4L, 3L, 5L, 4L, 4L, 2L, 4L, 5L, 4L, 3L, 4L, 5L, 3L, 4L, 4L, 
                                                                                                                          2L, 5L, 5L, 3L, 2L, 4L, 5L, 4L, 5L, 5L, 5L, 4L, 3L, 5L, 5L, 4L, 
                                                                                                                          4L, 3L, 4L, 4L, 5L, 5L, 3L, 4L, 5L, 2L, 4L, 4L, 5L, 4L, 5L, 5L, 
                                                                                                                          4L, 3L, 4L, 2L, 3L, 3L, 2L, 4L, 5L, 3L, 4L, 4L, 3L, 2L, 3L, 3L, 
                                                                                                                          5L, 4L, 5L, 2L, 2L, 4L, 5L, 3L, 4L, 2L, 5L, 3L, 5L, 3L, 4L, 4L, 
                                                                                                                          3L, 2L, 3L, 4L, 2L, 5L, 3L, 3L, 3L, 3L, 5L, 3L, 5L, 3L, 5L, 5L, 
                                                                                                                          5L, 4L, 3L, 5L, 3L, 2L, 4L, 4L, 1L, 4L, 2L, 3L, 3L, 3L, 5L, 4L, 
                                                                                                                          5L, 2L, 5L, 4L, 3L, 4L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 3L, 4L, 
                                                                                                                          4L, 5L, 5L, 4L, 3L, 4L, 4L, 3L, 2L), .Label = c("LTHS", "HS", 
                                                                                                                                                                          "LTBA", "BA", "PostBA"), class = "factor")), row.names = c(NA, 
                                                                                                                                                                                                                                     -346L), class = c("tbl_df", "tbl", "data.frame"))
dat_2 %>%
    tbl_uvregression(
        y = con,
        method = glm,
        method.args = list(family = binomial),
        exponentiate = TRUE,
        estimate_fun = purrr::partial(bounded_style_ratio, max = 2)
    )
#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred

#> Warning: glm.fit: fitted probabilities numerically 0 or 1 occurred
#> Warning in regularize.values(x, y, ties, missing(ties), na.rm = na.rm):
#> collapsing to unique 'x' values
#> Error in `mutate_cols()`:
#> ! Problem with `mutate()` column `ci`.
#> i `ci = if_else(...)`.
#> x must be a character vector, not a logical vector.
#> Caused by error in `glubort()`:
#> ! must be a character vector, not a logical vector.

reprex package (v2.0.1)

于 2022-02-10 创建

我了解有关数据拟合的警告,并且可能会在数据分析的下游丢弃此预测变量,但我不了解 mutate_cols() 部分中的错误是怎么回事。有谁知道我可以如何更新我的格式化调用来处理这个错误?

本例中置信区间的上限均为 NA,您定义的自定义函数不处理 NA 值。您需要更新它以处理 NA 值,它应该可以工作

bounded_style_ratio <- function(x, min = -Inf, max = Inf, ...) {
  dplyr::case_when(
    x < min ~ paste0("<", gtsummary::style_ratio(min, ...)),
    x > max ~ paste0(">", gtsummary::style_ratio(max, ...)),
    is.na(x) == TRUE ~ NA_character_,
    TRUE ~ gtsummary::style_ratio(x, ...)
  )
}

bounded_style_ratio(c(NA, NA))
#> Error in `glubort()`:
#> ! must be a character vector, not a logical vector.

reprex package (v2.0.1)

于 2022-02-10 创建

像这样的东西应该可以工作:

bounded_style_ratio <- function(x, min = -Inf, max = Inf, ...) {
  purrr::map_chr(
    x, 
    function(x) {
      if (isTRUE(x < min)) return(paste0("<", gtsummary::style_ratio(min, ...)))
      if (isTRUE(x > max)) return(paste0(">", gtsummary::style_ratio(max, ...)))
      gtsummary::style_ratio(x, ...)
    }
  )
}