Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tbl_uvregression() to accept survey objects #740

Merged
merged 7 commits into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 16 additions & 19 deletions R/tbl_svysummary.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,15 @@
tbl_svysummary <- function(data, by = NULL, label = NULL, statistic = NULL,
digits = NULL, type = NULL, value = NULL,
missing = NULL, missing_text = NULL, sort = NULL,
percent = NULL, include = NULL) {
percent = NULL, include = everything()) {
# checking for survey package ------------------------------------------------
assert_package("survey", "tbl_svysummary()")

# test if data is a survey object
if (!is_survey(data)) stop("'data' should be a survey object (see svydesign()).", call. = FALSE)

# eval -----------------------------------------------------------------------
include <- select(data$variables, {{ include }}) %>% names()

# default selection for include
if (length(include) == 0) {
# look at data$call
if (is.null(data$call)) {
include <- names(data$variables)
} else {
exclude <- c(
all.vars(data$call$id),
all.vars(data$call$probs),
all.vars(data$call$strata),
all.vars(data$call$fpc),
all.vars(data$call$weights)
)
include <- setdiff(names(data$variables), exclude)
}
}
include <- select(.remove_survey_cols(data), {{ include }}) %>% names()

# setting defaults from gtsummary theme --------------------------------------
label <- label %||%
Expand Down Expand Up @@ -576,3 +559,17 @@ c_form <- function(left = NULL, right = 1) {
right <- paste(right, collapse = "+")
stats::as.formula(paste(left, "~", right))
}


# this function removes the weight/survey columns from x$variables
# used when columns must be selected from the survey object, and we dont want users
# to select the weighting columns
.remove_survey_cols <- function(x) {
if (is.data.frame(x)) return(x)
x$variables %>%
select(-any_of(c(all.vars(x$call$id),
all.vars(x$call$probs),
all.vars(x$call$strata),
all.vars(x$call$fpc),
all.vars(x$call$weights))))
}
40 changes: 26 additions & 14 deletions R/tbl_uvregression.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#'
#' @param data Data frame to be used in univariate regression modeling. Data
#' frame includes the outcome variable(s) and the independent variables.
#' Survey design is also accepted.
#' @param method Regression method (e.g. [lm], [glm], [survival::coxph], and more).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add [survey::svyglm] in the list of possibilities ?

#' @param y Model outcome (e.g. `y = recurrence` or `y = Surv(time, recur)`).
#' All other column in `data` will be regressed on `y`.
Expand Down Expand Up @@ -106,6 +107,12 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a third example in the examples using a survey object

}

# checking input -------------------------------------------------------------
# data is a data frame
if (!is.data.frame(data) && !is_survey(data)) {
stop("`data` argument must be a data frame or survey object.", call. = FALSE)
}

# setting defaults -----------------------------------------------------------
pvalue_fun <-
pvalue_fun %||%
Expand Down Expand Up @@ -138,14 +145,18 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
y <- rlang::enexpr(y)
x <-
tryCatch({
.select_to_varnames(select = !!x, data = data, arg_name = "x")
.select_to_varnames(select = !!x,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "x")
}, error = function(e) {
rlang::expr_text(x)
})

y <-
tryCatch({
.select_to_varnames(select = !!y, data = data, arg_name = "y")
.select_to_varnames(select = !!y,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "y")
}, error = function(e) {
rlang::expr_text(y)
})
Expand All @@ -163,19 +174,19 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
include <-
.select_to_varnames(
select = {{ include }},
data = data,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "include"
)
exclude <-
.select_to_varnames(
select = {{ exclude }},
data = data,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "exclude"
)
show_single_row <-
.select_to_varnames(
select = {{ show_single_row }},
data = data,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "show_single_row"
)

Expand Down Expand Up @@ -205,7 +216,7 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
label <-
.formula_list_to_named_list(
x = label,
data = data,
data = switch(is.data.frame(data), data) %||% .remove_survey_cols(data),
arg_name = "label"
)

Expand All @@ -214,12 +225,6 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
stop("Each `label` specified must be a string of length 1.", call. = FALSE)
}

# data -----------------------------------------------------------------------
# data is a data frame
if (!is.data.frame(data)) {
stop("`data` argument must be a data frame.", call. = FALSE)
}

# will return call, and all object passed to in table1 call
# the object func_inputs is a list of every object passed to the function
tbl_uvregression_inputs <- as.list(environment())
Expand All @@ -229,7 +234,7 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL

# get all vars not specified -------------------------------------------------
all_vars <-
names(data) %>%
names(switch(is.data.frame(data), data) %||% .remove_survey_cols(data)) %>%
# removing x or y variable
setdiff(paste(c(y, x), "~ 1") %>% stats::as.formula() %>% all.vars()) %>%
# removing any other variables listed in the formula
Expand Down Expand Up @@ -263,10 +268,17 @@ tbl_uvregression <- function(data, method, y = NULL, x = NULL, method.args = NUL
formula_chr = glue(formula),
model = map(
.data$formula_chr,
~list(method, formula = as.formula(.x), data = data) %>%
function(.x) {
call_list1 <- # defining formula and data call (or formula and design)
switch(is.data.frame(data),
list(method, formula = as.formula(.x), data = data)) %||%
list(method, formula = as.formula(.x), design = data)

call_list1 %>%
c(as.list(method.args)[-1]) %>%
as.call() %>%
eval()
}
),
# removing backticks
y = switch(is.null(.env$y), all_vars) %||% y,
Expand Down
2 changes: 1 addition & 1 deletion man/tbl_svysummary.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/tbl_uvregression.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions tests/testthat/test-tbl_uvregression.R
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,25 @@ test_that("tbl_uvregression throw error with odd variable names in `data=`", {
trial %>% dplyr::rename(`age person` = age) %>% tbl_uvregression(method = lm, y = `age person`)
)
})

test_that("tbl_uvregression works with survey object", {
svy <- survey::svydesign(ids = ~1, data = trial, weights = ~1)

expect_error(
tbl_uvreg <-
svy %>%
tbl_uvregression(
y = response,
method = survey::svyglm,
method.args = list(family = binomial),
hide_n = TRUE,
include = c(response, age, marker, grade)
),
NA
)

expect_equal(
tbl_uvreg$tbls$age$model_obj %>% broom::tidy(),
survey::svyglm(response ~ age, design = svy, family = binomial) %>% broom::tidy()
)
})