Search code examples
rdplyrsurvey

find weighted frequency & se's for vector of variables


I would like to find the weighted frequencies with their SE's for all the variables in my data.

df <- data.frame(sex = c('F', 'M', 'F', 'M', 'M', 'M', 'F', 'F'),
                 married = c(1,1,1,1,0,0,1,1),
                 pens = c(0, 1, 1, 1, 1, 1, 0, 0),
                 weight = c(1.12, 0.55, 1.1, 0.6, 0.23, 0.23, 0.66, 0.67))

design <- svydesign(ids=~1, data=df, weights=~weight)

To get the weighted freqs for one variable:

svymean(~interaction(married), design)

                          mean     SE
interaction(married)0 0.089147 0.0717
interaction(married)1 0.910853 0.0717

My actual data set is large, and I want to run this on ALL the variables at once.

vars <- c("sex","married","pens")

I tried this, but it throws an error.

svymean(~interaction(reformulate(vars)), design)

Error in unique.default(x, nmax = nmax) : 
  unique() applies only to vectors

I can also do this--but running svytable does not help me, because I need the SE's.

for(i in  seq_along(vars)){
    print(prop.table(svytable(bquote(~.(as.name(vars[i]))), design)))
 }

EDIT

I want to run svymean(~interaction(var), design) on each variable in my df separately. So instead of having to run this many times like so:

svymean(~interaction(married), design)
svymean(~interaction(sex), design)
svymean(~interaction(pen), design)

I want to able to loop through this command for each variable in my vectored list of names (vars).

Any suggestions!??


Solution

  • We could use paste to create the formula

    out1 <- svymean(as.formula(paste0('~interaction(', toString(vars), ')')), design)
    
    out1
    #                                         mean     SE
    #interaction(sex, married, pens)F.0.0 0.000000 0.0000
    #interaction(sex, married, pens)M.0.0 0.000000 0.0000
    #interaction(sex, married, pens)F.1.0 0.474806 0.2109
    #interaction(sex, married, pens)M.1.0 0.000000 0.0000
    #interaction(sex, married, pens)F.0.1 0.000000 0.0000
    #interaction(sex, married, pens)M.0.1 0.089147 0.0717
    #interaction(sex, married, pens)F.1.1 0.213178 0.1945
    #interaction(sex, married, pens)M.1.1 0.222868 0.1567
    

    testing with manual entry

    out2 <- svymean(~interaction(sex,married, pens), design)
    identical(out1, out2)
    #[1] TRUE
    

    Update

    To do this separately, we can use lapply

    outlst1 <- lapply(vars, function(x) 
        svymean(as.formula(paste0('~interaction(', x, ')')), design))
    
    outlst1
    #[[1]]
    #                     mean     SE
    #interaction(sex)F 0.68798 0.1721
    #interaction(sex)M 0.31202 0.1721
    
    #[[2]]
    #                          mean     SE
    #interaction(married)0 0.089147 0.0717
    #interaction(married)1 0.910853 0.0717
    
    #[[3]]
    #                      mean     SE
    #interaction(pens)0 0.47481 0.2109
    #interaction(pens)1 0.52519 0.2109