Function inside of function

Hello,

A Posit Community member recently helped me with testing pairwise differences of proportions with survey data here. I attempted to wrap the solution into a more general function but ran into some problems. It's possible that the problem has to do with how I'm approaching the function that's inside the function here, but I'm not entirely sure (so hopefully the title of this post is not too misleading). Any help would be greatly appreciated. Much thanks.

suppressPackageStartupMessages(
  suppressWarnings({
    library(tidyverse)
    library(srvyr)
    library(survey)
    library(broom)
  }))  

# Minimal example
set.seed(5)
df <- data.frame(gender = rep(c("Female", "Male"), 50 ),
                 job_type = sample(c("type1", "type2", "type3"), 100, replace = TRUE),
                 smpl_wts = runif(100),
                 strat = sample(1:2, 100, replace = TRUE)) 

# Survey design object
df_design <- df %>% 
  as_survey_design(weight = smpl_wts,
                   strata = strat) 

# function to test pairwise differences
pwtest <- function(., y_var, x_var){
  
  levs <- (.) %>%
    mutate({{x_var}} := as.character({{x_var}})) %>%
    pull({{x_var}}) %>% 
    unique()
  
  pairs <- combn(levs, 2)
  
  test_diff <- function(i){
    
    v1 <- pairs[1, i]
    v2 <- pairs[2, i]
    
    (.) %>%
      filter({{x_var}} %in% c(v1, v2)) %>%
      mutate({{y_var}} := as.numeric({{y_var}})) %>%
      svyttest(eval(expr(!!ensym(y_var) ~ !!ensym(x_var))), design=.) %>%
      tidy() %>%
      mutate(group1=v1, group2=v2) %>%
      select(group1, group2, estimate, statistic, p=p.value)
    
  }
  
  1:ncol(pairs) %>%
    map(~test_diff) %>%
    bind_rows() %>%
    mutate(p.adj=p.adjust(p, method="bonferroni")) 
  
}

pwtest(df_design, gender, job_type)
#> Error in `bind_rows()`:
#> ! Argument 1 must be a data frame or a named atomic vector.
#> Backtrace:
#>     ▆
#>  1. ├─global pwtest(df_design, gender, job_type)
#>  2. │ └─1:ncol(pairs) %>% map(~test_diff) %>% bind_rows() %>% ...
#>  3. ├─dplyr::mutate(., p.adj = p.adjust(p, method = "bonferroni"))
#>  4. └─dplyr::bind_rows(.)
#>  5.   └─rlang::abort(glue("Argument {i} must be a data frame or a named atomic vector."))

Created on 2024-04-22 with reprex v2.0.2

Okay, so I see I wasn't paying close attention to variable types and was trying to convert a character vector to numeric. Changing the first call to mutate in the test_diff function, along with removing ~ in the call to map solved the problem:

mutate({{y_var}} := as.factor({{y_var}}) %>% as.numeric({{y_var}}))

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.