DanG
DanG

Reputation: 741

Curly curly operator inside survey function

I have a survey data with weight column like this dummy sample:

df <- structure(
  list(
    device = c(
      "Digital",
      "No Device",
      "No Device",
      "Digital",
      "Digital",
      "No Device",
      "Digital",
      "Digital",
      "Analouge",
      "Digital"
    ),
    sex = structure(c(1, 2, 2, 1, 1, 1, 1, 2, 2, 1), format.spss = "F8.2"),
    region = structure(c(15, 3, 18, 18, 30, 18, 54, 50, 30,
                         38), format.spss = "F8.0"),
    age_group = structure(c(3, 3,
                            5, 7, 6, 4, 7, 7, 6, 7), format.spss = "F8.2"),
    weight = structure(
      c(
        845.674012066483,
        523.065753702848,
        551.805833394951,
        454.282517089281,
        1234.09384828581,
        1046.04985735983,
        994.717870661103,
        1013.62211131793,
        1307.98181670913,
        544.360713556522
      ),
      format.spss = "F8.2"
    )
  ),
  row.names = c(NA,
                -10L),
  class = c("tbl_df", "tbl", "data.frame")
)

I am using srvyr package to make a survey object and do my analysis:

library(srvyr)
sv_sample <- df %>%
  srvyr::as_survey_design(weights = weight)

Here I am doing a cross tab interaction between device and sex for example and it is ok

sv_sample %>% 
  mutate(sex = as.factor(sex) )%>%
  mutate_at(vars(device),
            fct_explicit_na,
            na_level = "to_impute") %>%
  group_by(sex ,device) %>%
  summarize(
    proportion = srvyr::survey_mean(na.rm = TRUE),
    total = srvyr::survey_total(na.rm = TRUE)
  ) %>%
  select(-proportion_se, -total_se) %>%
  ungroup()

output:

# A tibble: 5 x 4
  sex   device    proportion total
  <fct> <fct>          <dbl> <dbl>
1 1     Digital        0.796 4073.
2 1     No Device      0.204 1046.
3 2     Analouge       0.385 1308.
4 2     Digital        0.298 1014.
5 2     No Device      0.316 1075.

I need to create similar cross tab for device vs other demo variables in my data like age , region , family_size etc etc so instead of copy & paste the cross tab snippet several times I tried to make a function with Curly curly operator. What am I missing here?

    crosstab <- function(survey_data, vars1 , vars2) {
      mutate(demo = as.factor{{ vars1 }} )%>%
        mutate_at(vars{{ vars2 }},
                  fct_explicit_na,
                  na_level = "to_impute") %>%
        group_by(demo ,{{ vars2 }}) %>%
        summarize(
          proportion = srvyr::survey_mean(na.rm = TRUE),
          total = srvyr::survey_total(na.rm = TRUE) ) %>%
        select(-proportion_se, -total_se) %>%
        ungroup()
}

 crosstab(sv_sample, sex ,device)

Upvotes: 0

Views: 152

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545865

Two things:

  1. vars{{ vars2 }} is invalid syntax. vars is a function: vars({{vars2}}). Same for as.factor.

  2. {{…}} interpolates a single value. If you want to pass multiple values, you either need to use !!! in combination with enquos or you can just pass the variables in dots (i.e. ...), no need for metaprogramming.

    However, in your case it seems as if you’re actually only passing a single variable name, so instead it would probably appropriate to rename vars1 and vars2 to var1 and var1 — or, better yet, give them proper names: var1 is an un-descriptive, cryptic variable name.

Instead of mutate_at(vars(...), f), also consider using its modern replacement, mutate(across(..., f)); this further simplifies your code. See Taking multiple columns without ....

Upvotes: 1

Related Questions