Question

I am trying to figure out how to subset a survey design objects dynamically. I have structured my loop to send in character strings, and don't know how to remove the quotes so R reads it as a call.

I would like to loop through some like this (although this will obviously break because SUBSET_VARIABLE %in% 4 needs to be a call NOT a string. :

design <- svydesign( ~1 , weight = ~wt , data = mtcars ) 

for( SUBSET_VARIABLE in c("gear","carb") ){

    design <- subset( design ,  SUBSET_VARIABLE %in% 4 )

    a <- svymean(~mpg, design)

}

If possible I would like to avoid defining the statement in a paste function and than using eval( parse ( text = statement ) ) ) to execute it. Also, I would like to avoid using indexing, because I know that the subset method for survey.design objects performs other tasks (see: getS3method("subset", "survey.design") ) and want to ensure that running the subset dynamically is exactly equivalent to using the subset function out of a loop. Thanks for any help you can provide

Matthew

Was it helpful?

Solution 2

Use eval and quote - I think that should allow you all of the flexibility you want:

for( SUBSET_VARIABLE in c(quote(gear), quote(carb)) ){
    design <- subset( design ,  eval(SUBSET_VARIABLE) %in% 4 )

    a <- svymean(~mpg, design)
}

Or if you want to have character strings as an input, you can use get instead:

for( SUBSET_VARIABLE in c("gear", "carb") ){
    design <- subset( design ,  get(SUBSET_VARIABLE) %in% 4 )

    a <- svymean(~mpg, design)
}

OTHER TIPS

This is a slightly different example with two solutions, one using a simple Loop and the other using lapply (which is faster). I hope this answer might be useful as well.

# Load Package
library(survey)

# Load Data
data(api)

# create survey design
dclus1 <- svydesign(id=~dnum, weights=~pw, data=apiclus1, fpc=~fpc)

# create object with all possible categories of variable dnum,
# which we will use to subset the survey design
groups <- unique(apiclus1$dnum)

# QUERIES

Using Simple Loop, distributing outputs into different data frames

for (i in groups) {
    temp <- svyby(~stype,
              ~dnum+cname,
              design = subset(dclus1, dnum == i),
              svytotal)
    assign(paste0("subgroup", i), temp)
    }

Using Lapply, binding outputs into one single data frame

tablefun <- function(i){svyby(~stype,
                                    ~dnum+cname,
                                    design = subset(dclus1, dnum == i),
                                    svytotal)}

results <- do.call(rbind, lapply(groups, tablefun))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top