3  Relabeling Qualtrics Variables

Qualtrics uses some random values like -99 to encode for things like skipped questions, “not sure” categories, or “not applicable” answers. Currently one needs to a dictionary to look up every variable to understand what each value means.

In addition, some response categories are confusing because they equate to a missing response. For example, from an analytical perspective an answer of “not sure” and skipping the question completely both equate to a missing value when the response categories are yes or no.

The memisc package was designed for working with survey data. It allows you to label response categories in the data and also designate different types of missingness (e.g. Unsure, N/A, and -99 can all be coded as missing).

Several factor and boolean variables in this survey data set have inconsistent coding. They are recoded in this section and the decision criteria are documented for inspection and review.

4 Yes/No Questions

Original Value Description Recode Value Code as Missing ?
Yes Yes 1 No
No No 0 No
Unsure Unsure 97 Yes
N/A Not Applicable 98 Yes
-99 Incomplete 99 Yes
NA Unanswered NA Yes
# APPLY TO COLUMNS K:
bool_qns <- 
  c( program_change_qns_bool, 
     fundraise_qns_bool, 
     cares_qns_bool, 
     finance_chng_qns_bool, 
     leadership_chng_qns_bool )

COLUMNS <-  bool_qns

# VALUES THAT NEED RECODING
RULES <- c(
  
           "  Yes    =>>    1    ", 
           "  No     =>>    0    ", 
           "  Unsure =>>    97   ", 
           "  N/A    =>>    98   ", 
           "  -99    =>>    99   "   )

rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]


# MEMISC LABELS AND MISSING VALUE CODES
values  <- c( 0, 1, 97, 98, 99 )
labels  <- c( "No", "Yes", "Unsure", "Not Applicable", "N/A" )
missing <- c( 97, 98, 99 )

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

PrgSrvc_IncrNum‘TYPE: boolean’

“Indicates an increase in number of programs or services”

Storage mode: character
Measurement: nominal
Missing values: 97, 98, 99

Values and labels N Valid Total
0 ‘No’ 268 40 . 1 38 . 8
1 ‘Yes’ 400 59 . 9 57 . 9
97 M ‘Unsure’ 1 0 . 1
98 M ‘Not Applicable’ 6 0 . 9
99 M ‘N/A’ 11 1 . 6
NA M 5 0 . 7

QUESTION TXT:
  1. In the last year (between January 2021-December 2021), did your organization make any of the following changes to your Programs, as compared to 2020? - Increased the number of programs or services

5 Single Checkboxes

These questions are presented as a checkbox to the respondent. They indicate an affirmative answer to the question.

5.1 Seek or Receive Fundraising Questions

These checkboxes are ticked by the respondent to indicate if they have sought or received funding from a specific source.

Original Value Description Recode Label Recode Value Code as Missing?
(select all that apply) Checkbox Checked Yes 1 No
-99 Checkbox Unchecked No 0 No
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  fundraise_skrcv_qns_bool

# VALUES THAT NEED RECODING

RULES <- c(    
  
  "  (select all that apply)    =>>    1    ", 
  "                      -99    =>>    0    "    )


rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1" )
labels  <- c( "No", "Yes" )
missing <- "UNSURE"

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

FndRaise_LocGvtGrnt_Seek‘TYPE: boolean’

“indicates if nonprofit sought a local government grant”

Storage mode: character
Measurement: nominal
Missing values: UNSURE

Values and labels N Valid Total
0 ‘No’ 317 46 . 8 45 . 9
1 ‘Yes’ 361 53 . 2 52 . 2
NA M 13 1 . 9

QUESTION TXT:
  1. In the last year (2021), did your organization seek or receive revenue from any of the followi… - Did you SEEK or APPLY for this funding? - Local government grants - (select all that apply)

5.2 Race and Gender Checkboxes

These checkboxes are ticked by the respondent to indicate if their CEO or board chair belong to a specified race or gender identity.

Original Value Description Recode Label Recode Value Code as Missing ?
Asian/Pacific Islander Checkbox Checked Yes 1 No
Black/African American Checkbox Checked Yes 1 No
Latinx/Hispanic Checkbox Checked Yes 1 No
Native American/American Indian Checkbox Checked Yes 1 No
White Checkbox Checked Yes 1 No
Man Checkbox Checked Yes 1 No
Woman Checkbox Checked Yes 1 No
Trans Checkbox Checked Yes 1 No
Gender non-conforming/Non-Binary Checkbox Checked Yes 1 No
Other (please specify) Checkbox Checked Yes 1 No
0 Checkbox Unchecked No 0 No
-99 Incomplete Incomplete 99 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  race_gender_qns_bool

# VALUES THAT NEED RECODING

RULES <- c(    
  
          "          Asian/Pacific Islander    =>>     1   ",
          "          Black/African American    =>>     1   ",
          "                 Latinx/Hispanic    =>>     1   ",
          " Native American/American Indian    =>>     1   ",
          "                           White    =>>     1   ",
          "                             Man    =>>     1   ",
          "                           Woman    =>>     1   ",
          "                           Trans    =>>     1   ",
          "Gender non-conforming/Non-Binary    =>>     1   ",
          "         Other (please specify):    =>>     1   ",
          "                             -99    =>>     x   ",
          "                               0    =>>     0   "     )


rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1", "x" )
labels  <- c( "No", "Yes", "Incomplete" )
missing <- "x"

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

CEOrace_AAPI‘TYPE: boolean’

“race of CEO”

Storage mode: character
Measurement: nominal
Missing values: x

Values and labels N Valid Total
0 ‘No’ 48 98 . 0 6 . 9
1 ‘Yes’ 1 2 . 0 0 . 1
x M ‘Incomplete’ 2 0 . 3
NA M 640 92 . 6

QUESTION TXT:
15.a. Which of the following best describes the race/ethnicity for your organization’s current Chief Executive (i.e., Executive Director or CEO)? (Select all that apply) - Selected Choice - Asian/Pacific Islander

5.3 N/A Checkboxes

These questions are presented as a checkbox to the user to indicate that a question is not applicable. “Yes” here means “Yes, this question is not applicable”.

Original Value Description Recode Label Recode Value Code as Missing ?
C Yes, this question is not applicable Yes 1 No
N/A Yes, this question is not applicable Yes 1 No
-99 Incomplete No 0 No
NA Unanswered NA NA Yes
na_bool_qns <- 
  c( staff_qns_bool, 
     reserve_qns_bool, 
     people_served_qns_bool )


# APPLY TO COLUMNS K:
COLUMNS <-  na_bool_qns

# VALUES THAT NEED RECODING

RULES <- c(    
          
             "    C    =>>     1   ", 
             "  -99    =>>     0   ", 
             "  N/A    =>>     1   "     )


rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1" )
labels  <- c( "No", "Yes" )
missing <- NULL

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

Staff_Fulltime_NA‘TYPE: boolean’

“Number of full time staff not applicable”

Storage mode: character
Measurement: nominal

Values and labels N Valid Total
0 ‘No’ 638 92 . 9 92 . 3
1 ‘Yes’ 49 7 . 1 7 . 1
NA M 4 0 . 6

QUESTION TXT:
STAFF & VOLUNTEERS      6. How many (paid and unpaid) people in your organization will have worke… - Check here if not applicable for your organization - Full-time paid staff (35 or more hours /week) - C

6 Multi-selection Inputs

These questions offer the user with multiple options to select one from. Since the options are ordered categories, they are coded on an ordinal scale.

6.1 Increase - Decrease Questions

There 2 questions that ask respondents to define changes via an increase or decrease relative to previous years. They are recoded on an ordinal scale.

6.2 Changes in Demand Questions

Original Value Description Recode Label Recode Value Code as Missing ?
Increase Increase Increase 2 No
Stay the same Stay the same Unchanged 1 No
Decrease Decrease Decrease 0 No
-99 Incomplete No 99 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  demand_fct_qns

# VALUES THAT NEED RECODING

RULES <- c(    
          
             "        Decrease    =>>     0   ",
             "   Stay the same    =>>     1   ", 
             "        Increase    =>>     2   ", 
             "             -99    =>>     x   "    )


rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( 2, 1, 0, "x" )
labels  <- c( "Increase", "Unchanged", "Decrease", "Incomplete" )
missing <- "x"

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

Dmnd_NxtYear‘TYPE: factor’

“Demand for programs or services next year”

Storage mode: character
Measurement: nominal
Missing values: x

Values and labels N Valid Total
0 ‘Decrease’ 17 2 . 5 2 . 5
1 ‘Unchanged’ 148 21 . 9 21 . 4
2 ‘Increase’ 512 75 . 6 74 . 1
x M ‘Incomplete’ 10 1 . 4
NA M 4 0 . 6

QUESTION TXT:
  1. In the next year, do you anticipate the demand for your programs to decrease, stay the same, or increase?

6.3 Changes in Fundraising Questions

Original Value Description Recode Label Recode Value Code as Missing ?
Increased significantly (by more than 10%) Largest Increase Increase Significantly 5 No
Increased moderately (by less than 10%) Second Largest Increase Increase Moderately 4 No
Stayed more or less the same Third Largest Increase Unchanged 3 No
Decreased moderately (by less than 10%) Fourth Largest Increase Decrease Moderately 2 No
Decreased significantly (by more than 10%) Fifth Largest Increase Decrease Significantly 1 No
Unsure Unsure Unsure 99 Missing
-99 Incomplete Incomplete 98 Yes
N/A Not Applicable Not Applicable 97 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  fundraise_change_qns_fct

# VALUES THAT NEED RECODING

RULES <- c(    
          
     "   Increased significantly (by more than 10%)    =>>     5   ",
     "      Increased moderately (by less than 10%)    =>>     4   ",
     "                 Stayed more or less the same    =>>     3   ",
     "      Decreased moderately (by less than 10%)    =>>     2   ",
     "   Decreased significantly (by more than 10%)    =>>     1   ",
     "                                       Unsure    =>>     0   ",
     "                                          -99    =>>     X   ",
     "                                          N/A    =>>   N/A   "  )
 
rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( 5, 4, 3, 2, 1, 0, "X", "N/A" )
labels  <- c( "Increase Significantly", "Increase Moderately", 
              "Unchanged", "Decrease Moderately", "Decrease Significantly", 
              "Unsure", "Incomplete", "Not Applicable" )
missing <- c( "X" )

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

FndRaise_Overall_Chng‘TYPE: factor’

“change in overall donations”

Storage mode: character
Measurement: nominal
Missing values: X

Values and labels N Valid Total
0 ‘Unsure’ 12 1 . 9 1 . 7
1 ‘Decrease Significantly’ 80 12 . 6 11 . 6
2 ‘Decrease Moderately’ 77 12 . 1 11 . 1
3 ‘Unchanged’ 161 25 . 4 23 . 3
4 ‘Increase Moderately’ 169 26 . 7 24 . 5
5 ‘Increase Significantly’ 133 21 . 0 19 . 2
N/A ‘Not Applicable’ 2 0 . 3 0 . 3
X M ‘Incomplete’ 33 4 . 8
NA M 24 3 . 5

QUESTION TXT:
8.c. To the best of your knowledge, has each of the following categories of donations to your org… - In 2021 compared to 2020 - Overall donations

7 Level of Importance Questions

There are 2 questions that ask respondents to rank the importance of volunteers and donors respectively. However, both sets of options’ are not identical. Hence, they are recoded to common values for reproducibility.

7.1 Volunteer Importance

Original Value Description Recode Label Recode Value Code as Missing ?
Essential - we depend entirely on volunteers to carry out our mission and goals Maximum Importance Essential 5 No
Very important - we depend on volunteers for a wide range of tasks, but not all Second Most Important Very Important 4 No
Somewhat important - we depend on volunteers for several key tasks Third Most Important Somewhat Important 3 No
Not very important - we depend on volunteers for only non-essential tasks Fourth Most Important Not Very Important 2 No
Not at all important - we could carry out our mission and goals without using volunteers Fifth Most Important Not At All Important 1 No
We do not use volunteers Sixth Most Important Not Used 0 No
-99 Incomplete Incomplete 99 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  volimportance_qns_fct

# VALUES THAT NEED RECODING

RULES <- c(    

"           Essential - we depend entirely on volunteers to carry out our mission and goals    =>>     5   ",
"           Very important - we depend on volunteers for a wide range of tasks, but not all    =>>     4   ",
"                        Somewhat important - we depend on volunteers for several key tasks    =>>     3   ",
"                 Not very important - we depend on volunteers for only non-essential tasks    =>>     2   ",
"  Not at all important - we could carry out our mission and goals without using volunteers    =>>     1   ",
"                                                                  We do not use volunteers    =>>     0   ",
"                                                                                       -99    =>>     X   "    )

rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( 5, 4, 3, 2, 1, 0, "X" )
labels  <- c( "Essential", "Very Important", "Somewhat Important", 
              "Not Very Important", "Not At All Important", "Not Used", 
              "Incomplete" )
missing <- c( "X" )

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

VolImportance‘TYPE: factor’

“Importance of volunteers to organization”

Storage mode: character
Measurement: nominal
Missing values: X

Values and labels N Valid Total
0 ‘Not Used’ 45 6 . 6 6 . 5
1 ‘Not At All Important’ 39 5 . 7 5 . 6
2 ‘Not Very Important’ 74 10 . 9 10 . 7
3 ‘Somewhat Important’ 188 27 . 6 27 . 2
4 ‘Very Important’ 200 29 . 4 28 . 9
5 ‘Essential’ 135 19 . 8 19 . 5
X M ‘Incomplete’ 6 0 . 9
NA M 4 0 . 6

QUESTION TXT:
  1. How important were volunteers – other than board members – to the work your organization conducted in 2021?

7.2 Donor Importance

Original Value Description Recode Label Recode Value Code as Missing ?
Essential, we depend entirely on individual donations to carry out our mission and goals Maximum Importance Essential 5 No
Very important, we depend on individual donations for a wide range of activities, but not all Very Important 4 No
Important, we depend on individual donations for several key activities Third Most Important Somewhat Important 3 No
Not very important, we depend on individual donations for only non-essential activities Fourth Most Important Not Very Important 2 No
Not at all important, we could carry out our mission and goals without donations from individuals Fifth Most Important Not At All Important 1 No
We do not receive donations from individuals Sixth Most Important Not Used 0 No
-99 Incomplete Incomplete 99 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  donimportance_qns_fct

# VALUES THAT NEED RECODING

RULES <- c(    

  "          Essential, we depend entirely on individual donations to carry out our mission and goals  =>>  5  ",
  "     Very important, we depend on individual donations for a wide range of activities, but not all  =>>  4  ",
  "                           Important, we depend on individual donations for several key activities  =>>  3  ",
  "           Not very important, we depend on individual donations for only non-essential activities  =>>  2  ",
  " Not at all important, we could carry out our mission and goals without donations from individuals  =>>  1  ",
  "                                                      We do not receive donations from individuals  =>>  0  ",
  "                                                                                               -99  =>>  X  "  )


rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c(5, 4, 3, 2, 1, 0, "X" )
labels  <- c( "Essential", "Very Important", 
              "Somewhat Important", "Not Very Important", 
              "Not At All Important", "Not Used", "Incomplete")
missing <- c( "X" )

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

DonImportance‘TYPE: factor’

“importance of donors to organization”

Storage mode: character
Measurement: nominal
Missing values: X

Values and labels N Valid Total
0 ‘Not Used’ 18 2 . 6 2 . 6
1 ‘Not At All Important’ 24 3 . 5 3 . 5
2 ‘Not Very Important’ 56 8 . 2 8 . 1
3 ‘Somewhat Important’ 132 19 . 4 19 . 1
4 ‘Very Important’ 282 41 . 5 40 . 8
5 ‘Essential’ 168 24 . 7 24 . 3
X M ‘Incomplete’ 7 1 . 0
NA M 4 0 . 6

QUESTION TXT:
  1. How important were donations from individuals (including direct donations and indirect donations through federated giving programs, United Way, and donor advised funds, or in-kind donations) to the work of your organization in 2021?

8 Frequency Questions

These questions ask respondents to rank the frequency at which they engage in an activity.

Original Value Description Recode Label Recode Value Code as Missing ?
Almost all the time Most Frequent Most of the time 4 No
Frequently Second Most Frequent Frequently 3 No
Occasionally Third Most Frequent Occasionally 2 No
Rarely Fourth Most Frequent Rarely 1 No
Never Fifth Most Frequent Occasionally 0 No
-99 Incomplete Incomplete 99 Yes
NA Unanswered NA NA Yes
# APPLY TO COLUMNS K:
COLUMNS <-  extaffairs_qns_fct

# VALUES THAT NEED RECODING

RULES <- c(    

     "    Almost all the time    =>>     4   ",
     "             Frequently    =>>     3   ",
     "           Occasionally    =>>     2   ",
     "                 Rarely    =>>     1   ",
     "                  Never    =>>     0   ",
     "                    -99    =>>     X   "   )
     
rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( 4, 3, 2, 1, 0, "X" )
labels  <- c( "Most of the time", "Frequently",  
              "Occasionally", "Rarely", "Never", "Incomplete" )
missing <- c( "X" )

# RECODE VARIABLES 
survey_df <- 
  survey_df %>% 
  recode_columns( k=COLUMNS, pattern, replace, values, labels, missing )

Example:

ExtAffairs_GenEd‘TYPE: factor’

“frequency of activities aimed at educating the general public about a specific policy issue and/or the interests of certain groups”

Storage mode: character
Measurement: nominal
Missing values: X

Values and labels N Valid Total
0 ‘Never’ 167 29 . 0 24 . 2
1 ‘Rarely’ 98 17 . 0 14 . 2
2 ‘Occasionally’ 149 25 . 9 21 . 6
3 ‘Frequently’ 116 20 . 2 16 . 8
4 ‘Most of the time’ 45 7 . 8 6 . 5
X M ‘Incomplete’ 10 1 . 4
NA M 106 15 . 3

QUESTION TXT:
EXTERNAL AFFAIRS 16. During the last two years (2020-2021), how often did your organization conduct the following activities? (Including at the local, county, state, or federal level). - Educate the general public about a specific policy issue and/or the interests of certain groups

9 Integer Inputs

These questions accept an integer input from users to indicate the number of staff they have, people they served, or donors they have.

Original Value Description Recode Label Recode Value Code as Missing ?
Whole Number Number of Staff, People or Donors NA Integer Value No
N/A Not Applicable NA -1 Yes
-99 Incomplete NA -2 Yes
NA Unanswered NA NA Yes
int_qns <- 
  c( staff_qns_int, 
     people_served_qns_int, 
     fundraise_donor_qns_int )

COLUMNS <- int_qns

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>%
  lapply( recode_x, pattern=c("N/A","-99"), replace=c("Inf","Inf") )

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>%
  lapply( as.numeric )

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>%
  lapply( memisc::as.item, missing.values=Inf )

survey_df[ COLUMNS ] <- purrr::map( COLUMNS, add_q_details, survey_df )

Example:

Staff_Fulltime_2021‘TYPE: integer’

“Number of full time staff”

Storage mode: double
Measurement: interval
Missing values: Inf

Values and labels N Percent
M (unlab.mss.) 61 8 . 8
NA M 4 0 . 6

Min: 0 . 000
Max: 3000 . 000
Mean: 17 . 119
Std.Dev.: 122 . 704

QUESTION TXT:
STAFF & VOLUNTEERS      6. How many (paid and unpaid) people in your organization will have worke… - 2021 - Full-time paid staff (35 or more hours /week) - (best estimate)

10 Numeric Inputs

These questions accept a numeric input from users to denote dollar values. For some variables, additional processing is done to remove commas and “$” signs.

Original Value Description Recode Label Recode Value Code as Missing ?
Dollar Amount Dollar Amount NA Numeric Value No
-99 Incomplete NA -1 Yes
NA Unanswered NA NA Yes
numeric_qns <- 
  c( majorgift_qn_num, 
     reserve_qns_num, 
     cares_qns_num, 
     finance_revenue_qns_num )

COLUMNS <- numeric_qns

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( keep_numbers )

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>%
  lapply( memisc::as.item, missing.values=Inf )

survey_df[ COLUMNS ] <- purrr::map( COLUMNS, add_q_details, survey_df )

Example:

FndRaise_MajGift_Amt‘TYPE: numeric’

“donation amount considered a major gift”

Storage mode: double
Measurement: interval
Missing values: Inf

Values and labels N Percent
M (unlab.mss.) 18 2 . 6
NA M 25 3 . 6

Min: 0 . 010
Max: 1000000 . 000
Mean: 5935 . 894
Std.Dev.: 44801 . 714

QUESTION TXT:
8.b. What is the smallest donation amount that your organization would consider to be a major gift? - $

11 Text Inputs

These questions allow the user to enter raw text as answers. All non-text values are converted to NAs.

text_qns <- 
  c( staff_qns_text, 
     finance_chng_qns_text, 
     finance_revenue_qns_text, 
     fundraise_qns_text, 
     leadership_chng_qns_text, 
     primary_cncrn_qn_text, 
     program_change_qns_txt, 
     race_gender_qns_text)

survey_df[ text_qns ] <- 
  survey_df[ text_qns ] %>%
  lapply( recode_x, pattern="-99", replace=NA )

survey_df[ text_qns ] <- 
  survey_df[ text_qns ] %>%
  lapply( memisc::as.item )

survey_df[ text_qns ] <- purrr::map( text_qns, add_q_details, survey_df )

codebook( survey_df[ text_qns[1] ] )
================================================================================

   Staff_Other_Text_2021 'TYPE: text'

   "Description of other staff"

--------------------------------------------------------------------------------

   Storage mode: character
   Measurement: nominal

   Min:                     "Book keeper"
   Max: "we are a part time organization"

   QUESTION TXT:
       STAFF & VOLUNTEERS      6. How many (paid and unpaid) people in
       your organization will have worke... - 2021 - Other (please
       specify): - Text

Example:

Staff_Other_Text_2021‘TYPE: text’

“Description of other staff”

Storage mode: character
Measurement: nominal

Min: “Book keeper”
Max: “we are a part time organization”

QUESTION TXT:
STAFF & VOLUNTEERS      6. How many (paid and unpaid) people in your organization will have worke… - 2021 - Other (please specify): - Text