This vignette shows how to use qsurvey to download and work with responses collected with the Qualtrics survey platform. Before continuing you should have installed qsurvey; see the installation instructions.

library(qsurvey)

Retrieve survey responses

We’ll start by downloading the responses to a survey called “Demographics.”

(survey_id <- find_id("Demographics"))
#>         Demographics 
#> "SV_0VVlb9QwJ4bsBKZ"

responses() sends a request to the Qualtrics API for our response data and waits while the survey platform prepares the export. After downloading it, responses() returns the data.

demographics = responses(survey_id)
class(demographics)
#> [1] "data.table" "data.frame"
dim(demographics)
#> [1] 100  54

By default, responses() gives a table showing choice text or labels. This means that if the respondent-facing answer choices for a question are "Low", "Medium", and "High", the response data will contain these strings. Alternatively, if argument use_labels = FALSE, the response data will show the choice ids "1", "2", and "3", or if choice recodes have been configured, perhaps "-1", "0", and "1".

head(demographics$Q23)
#> [1] "Republican" "Democratic" "Republican" "Republican" ""          
#> [6] "Republican"
demographics_nolabels = responses(survey_id, use_labels = FALSE)
head(demographics_nolabels$Q23)
#> [1] "1" "2" "1" "1" ""  "1"

As described in the documentation for response(), other Qualtrics API parameters that affect the format of survey responses are available. For example, passing argument seenUnansweredRecode = “99” to responses() will show "99" as the response to unanswered questions instead of NA, the default. See the Qualtrics documentation if you need to customize output from responses().

Dropping columns

Let’s take a look at the columns in the response data. The first five are survey and respondent metadata. If they aren’t useful to us, we can drop them with the drop_meta() function. We’re left with actual survey responses and the eight columns named DO-* that give question display orders.

names(demographics)
#>  [1] "ResponseID"            "ResponseSet"          
#>  [3] "IPAddress"             "StartDate"            
#>  [5] "EndDate"               "RecipientLastName"    
#>  [7] "RecipientFirstName"    "RecipientEmail"       
#>  [9] "ExternalDataReference" "Finished"             
#> [11] "Status"                "Q1"                   
#> [13] "Q2"                    "Q3"                   
#> [15] "Q4"                    "Q5_1"                 
#> [17] "Q5_2"                  "Q5_3"                 
#> [19] "Q5_4"                  "Q5_5"                 
#> [21] "Q5_6"                  "Q5_6_TEXT"            
#> [23] "Q6"                    "Q7"                   
#> [25] "Q8"                    "Q9"                   
#> [27] "Q11"                   "Q10"                  
#> [29] "Q12"                   "Q14"                  
#> [31] "Q13"                   "Q15"                  
#> [33] "Q15_TEXT"              "Q16"                  
#> [35] "Q17"                   "Q18"                  
#> [37] "Q19"                   "Q26"                  
#> [39] "Q20"                   "Q20_TEXT"             
#> [41] "Q21"                   "Q22"                  
#> [43] "Q23"                   "Q24_1"                
#> [45] "Q25"                   "Q25_TEXT"             
#> [47] "DO-Q-Q9"               "DO-Q-Q11"             
#> [49] "DO-Q-Q15"              "DO-Q-Q17"             
#> [51] "DO-Q-Q18"              "DO-Q-Q19"             
#> [53] "DO-Q-Q20"              "DO-Q-Q25"
demographics <- drop_meta(demographics)
names(demographics)
#>  [1] "Q1"        "Q2"        "Q3"        "Q4"        "Q5_1"     
#>  [6] "Q5_2"      "Q5_3"      "Q5_4"      "Q5_5"      "Q5_6"     
#> [11] "Q5_6_TEXT" "Q6"        "Q7"        "Q8"        "Q9"       
#> [16] "Q11"       "Q10"       "Q12"       "Q14"       "Q13"      
#> [21] "Q15"       "Q15_TEXT"  "Q16"       "Q17"       "Q18"      
#> [26] "Q19"       "Q26"       "Q20"       "Q20_TEXT"  "Q21"      
#> [31] "Q22"       "Q23"       "Q24_1"     "Q25"       "Q25_TEXT" 
#> [36] "DO-Q-Q9"   "DO-Q-Q11"  "DO-Q-Q15"  "DO-Q-Q17"  "DO-Q-Q18" 
#> [41] "DO-Q-Q19"  "DO-Q-Q20"  "DO-Q-Q25"

drop_sensitive() and keep_questions() are similar to drop_meta(), but target different column ranges.

Renaming variables

By default, the response table’s variable names are the descriptive export names given to each question in the Qualtrics Control Panel. Let’s instead name them according to the unique identifiers of questions. We’ll need the survey’s design to access these; we pass it and the table of responses to names_to_ids().

demo_design <- design(survey_id)
demographics <- names_to_ids(demographics, demo_design)
names(demographics)
#>  [1] "QID132224442" "QID132224453" "QID132224461" "QID132224462"
#>  [5] "QID132224463" "QID132224463" "QID132224463" "QID132224463"
#>  [9] "QID132224463" "QID132224463" "QID132224463" "QID132224464"
#> [13] "QID132224465" "QID132224466" "QID132224467" "QID132224444"
#> [17] "QID132224443" "QID132224445" "QID132224447" "QID132224446"
#> [21] "QID132224448" "QID132224448" "QID132224449" "QID132224450"
#> [25] "QID132224451" "QID132224452" "QID132224460" "QID132224454"
#> [29] "QID132224454" "QID132224455" "QID132224456" "QID132224457"
#> [33] "QID132224458" "QID132224459" "QID132224459" "DO-Q-Q9"     
#> [37] "DO-Q-Q11"     "DO-Q-Q15"     "DO-Q-Q17"     "DO-Q-Q18"    
#> [41] "DO-Q-Q19"     "DO-Q-Q20"     "DO-Q-Q25"

ids_to_names() does the reverse.

# FIXME: need to preserve suffixes for eg Q5_1, Q5_2   
# demographics <- ids_to_names(demographics, demo_design)
# names(demographics)

Conclusion

After downloading survey response data with responses(), two sets of convenience functions are available: one for dropping/keeping columns, and another for renaming columns. If you have a question or suggestion, please open a GitHub issue.