Find the standard error of weighted proportions (survey data)

Viewed 194

I have created a user function to generate cross tables for my categorical survey data. For example, I have written a function to find Q50_1 by gender. It looks great.

enter image description here

But now, would like to add a column, with the corresponding SE for each row, but I cannot figure out a solution. Here is my desired output (the SE's are fake in this example).

enter image description here

Here is my data:

data_in <- read_table2("Q50_1   Q50_2   Q38 Q90 pov gender  wgt
never   always   Yes 2   High    M   1.3
sometimes   always   No  2   Med F   0.4
always   sometimes   Yes 4   Low F   1.2
never   never   No  2   High    M   0.5
always   always   No  4   High    M   0.7
sometimes   never   Yes 3   Low F   0.56
sometimes   never   Yes 2   Med F   0.9
")

Here is the function I created to generate the cross tables:

library(tidyverse)
library(pollster)
# USER FUNCTION THAT RUNS CROSS TABS (FEEDS INTO NEXT FUNCTION)
xtab_func <- function(data, col, target,weight){
  col <- sym(col)
  target <- enquo(target)
  weight <- enquo(weight)
  pollster::crosstab(df = data, !!target, !!col, !!weight, format = "long") %>% pivot_longer(cols = starts_with("Q"))
}




crosstab <- function(data, target, columns, weight,target_name){
  
  target <- enquo(target)
  weight <- enquo(weight)
  target_name <- enquo(target_name)

  d <- list()
  
  for (i in columns){
    x <- xtab_func(data, i, !!target,!!weight)
    x$i <- i
    
    d[[i]] <- x
    df <- do.call(rbind, d) %>% 
      rename(group = !!target,
             question = name) %>%
      mutate(group_level =!!target_name) %>% 
      select(-i)
  }  
  return(df)
  
  
}


crosstab(data_in,gender, c("Q50_1","Q50_2"),wgt,"gender")

This post shows the math behind it, but I cannot find anything on the application. Any help is appreciated!

EDIT

I could use pollster:moe_crosstab to produce the margin of error, but pollster does not seem to have a way to add the standard error.

enter image description here

1 Answers

We could modify the function to compute margin of error (moe_crosstab) and calculate the standard error based on the confidence interval level

library(dplyr)
library(purrr)
library(tidyr)
library(pollster)
crosstab <- function(data, target, columns, weight,target_name, zval){
  
  target <- enquo(target)
  weight <- enquo(weight)
  target_name <- enquo(target_name)
   return(purrr::map_dfr(columns, ~    xtab_func(data,
             .x, !!target, !!weight, zval))) 
  
}




xtab_func <- function(data, col, target, weight, zval){
   col <- sym(col)
   target <- enquo(target)
   weight <- enquo(weight)
   pollster::crosstab(df = data, !!target, !!col, !!weight, format = "long") %>% 
      bind_cols(pollster::moe_crosstab(df = data, !!col,
                  !!target, !! weight) %>%
              transmute(SE = moe/zval)) %>%  
      pivot_longer(cols = starts_with("Q")) 
}

-testing

crosstab(data_in,gender, c("Q50_1", "Q50_2"), wgt, "gender", 1.96)
Related