8  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.

9 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, 
     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’ 192 38 . 7 38 . 2
1 ‘Yes’ 304 61 . 3 60 . 6
98 M ‘Not Applicable’ 3 0 . 6
99 M ‘N/A’ 1 0 . 2
NA M 2 0 . 4

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

Original Value Description Recode Value Code as Missing ?
Yes Yes 1 No
No No 2 No
Unsure Unsure 3 Yes
N/A Not Applicable 98 Yes
-99 Incomplete 99 Yes
NA Unanswered NA Yes
# APPLY TO COLUMNS K:

COLUMNS <- cares_qns_bool

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

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


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

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

Example:

CARES_Rcv‘TYPE: boolean’

“Indicates whether organization receive government funding from CARES act”

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

Values and labels N Valid Total
1 ‘Yes’ 172 41 . 1 34 . 3
2 ‘No’ 247 58 . 9 49 . 2
3 M ‘Unsure’ 16 3 . 2
NA M 67 13 . 3

QUESTION TXT:
In the last year (2022, or your last fiscal year), did your organization receive any government funding to help your organization respond to the COVID-19 pandemic (including funding from federal, state, or local government programs)?

10 Single Checkboxes

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

10.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?
1 Checkbox Checked Yes 1 No
NA Checkbox Unchecked No 0 No
All NA Unanswered NA NA Yes

ALL NA refers to no responses on all questions in this entire question group (i.e. the respondent skipped the section).

# APPLY TO COLUMNS K:
COLUMNS <-  fundraise_skrcv_qns_bool


# ALL RESPONSES NA IN GROUP:
# indication that the question
# was skipped by the respondent

row.id <- apply( survey_df[ COLUMNS ], 
                 MARGIN = 1, 
                 FUN = function(x) all(is.na(x)) ) 

# NA means "no"

na_to_zero <- function(x){
  x[ is.na(x) ] <- 0
  return(x)
}

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

# if they do not respond "yes" 
# to at least one question then
# assume they skipped them all

zero_to_na <- function( x, rowid ){
  x[ rowid ] <- NA
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( zero_to_na, row.id )



# VALUES THAT NEED RECODING

RULES <- c(    
  
  "    1      =>>    1    ", 
  "   NA      =>>    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 <- NA

# 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: NA

Values and labels N Percent
0 ‘No’ 228 45 . 4
1 ‘Yes’ 274 54 . 6

QUESTION TXT:
In the last year (2022), 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)

10.2 Regulation 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 ?
1 Checkbox Checked Yes 1 No
NA Unanswered No 0 No
22 Checkbox Checked Yes 1 No
21 Unchecked Box No 0 No
# APPLY TO COLUMNS K:

# exclude OTHER TXT question
other <- which( regulation_qns == "Regulations_Other_TEXT" )
COLUMNS <-  regulation_qns[ - other  ]


# "did not contact any agencies":
# ~ NONE CONTACTED

dnc.rows <- survey_df$Regulations == 21 

# all rows NA: 
# question skipped by respondent

na.rows <- is.na( survey_df$Regulations )


# NA means "NO"

na_to_zero <- function(x){
  x[ is.na(x) ] <- 0
  return(x)
}

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


# if they responded "NONE CONTACTED" (21) 
# to the first question code
# the rest as "NONE CONTACTED"

zero_to_dnc <- function( x, rowid ){
  x[ rowid ] <- "NONE"
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( zero_to_dnc, rowid=dnc.rows )

# if the first question was NA 
# code all as missing ("no response")

zero_to_noresp <- function( x, rowid ){
  x[ rowid ] <- "_NR_"
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( zero_to_noresp, rowid=na.rows )


# VALUES THAT NEED RECODING

RULES <- c(    "   22    =>>     1                ",
               "   21    =>>     NONE             ",
               "   NA    =>>     _NA_             "    )


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


# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1", "NONE", "_NR_", "_NA_" )
labels  <- c( "No", "Yes", "None Contacted", "No Response", "Missing" )
missing <- "_NA_"

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

Example:

Regulations‘TYPE: boolean’

“Indicates whether the nonprofit contacted federal, state, or local regulatory agencies in the past 2 years”

Storage mode: character
Measurement: nominal
Missing values: NA

Values and labels N Percent
NR ‘No Response’ 63 12 . 5
0 ‘No’ 0 0 . 0
1 ‘Yes’ 156 31 . 1
NONE ‘None Contacted’ 283 56 . 4

QUESTION TXT:
Has your organization contacted federal, state or local regulatory agencies (IRS, State Attorney Generals, Secretaries of State, or other state or local charities regulation officials) in the past 2 years?

Regulations_Local‘TYPE: boolean’

“Indicates whether the nonprofit has contacted local regulatory agencies in the past 2 years”

Storage mode: character
Measurement: nominal
Missing values: NA

Values and labels N Percent
NR ‘No Response’ 63 12 . 5
0 ‘No’ 60 12 . 0
1 ‘Yes’ 96 19 . 1
NONE ‘None Contacted’ 283 56 . 4

QUESTION TXT:
Please indicate below the types of agencies (check all that apply): - Local

10.3 Staffing Plans

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 ?
1 Checkbox Checked Yes 1 No
NA Unanswered No 0 No
# APPLY TO COLUMNS K:
COLUMNS <-  staffing_plans


# ALL RESPONSES NA IN GROUP:
# indication that the question
# was skipped by the respondent

row.id <- apply( survey_df[ COLUMNS ], 
                 MARGIN = 1, 
                 FUN = function(x) all(is.na(x)) ) 

# VALUES THAT NEED RECODING

RULES <- c(    
          
             "    1    =>>     1   ", 
             "   NA    =>>     0   "   )


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

# NA means "no"

na_to_zero <- function(x){
  x[ is.na(x) ] <- 0
  return(x)
}

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

# if they do not respond "yes" 
# to at least one question then
# assume they skipped them all

zero_to_na <- function( x, rowid ){
  x[ rowid ] <- NA
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( zero_to_na, row.id )

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

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

Example:

StaffingPlans_HireDifferent‘TYPE: boolean’

“Indicates whether the nonprofit has plans to hire new staff with different skills than existing staff in the next 12 months”

Storage mode: character
Measurement: nominal
Missing values: NA

Values and labels N Percent
0 ‘No’ 329 65 . 5
1 ‘Yes’ 173 34 . 5

QUESTION TXT:
Does your organization have plans to change its staffing in the next 12 months? (select all that apply) - Hire new staff with different skills than existing staff

10.4 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”.

10.4.1 Staff Forecasts

We see three four cases:

  • All answered
  • Only answer for 2022 but don’t forecast 2023
  • Answer “does not apply to me”
  • Answer “does apply” but then don’t report numbers

We create an imputed version of 2023 numbers using 2022 numbers for missing cases (new variable x_2023 is saved as x_2023_imp for “imputed” ).

Replace “OK” in the not applicable field with “UNSURE” if they report no staff numbers. These will become NA (missing) when the dataset is saved.

    Staff_Fulltime_2022 Staff_Fulltime_2023 Staff_Fulltime_NA
142                 100                 110                 0
144                   1                   1                 0
145                 210                 225                 0
143                   1                  NA                 0
146                   0                  NA                 0
141                  NA                  NA                 1
150                  NA                  NA                 0

After imputation of 2023 responses (use 2022 values):

    Staff_Fulltime_2022 Staff_Fulltime_2023 Staff_Fulltime_NA
142                 100                 110                 0
144                   1                   1                 0
145                 210                 225                 0
143                   1                   1                 0
146                   0                   0                 0
141                  NA                  NA                 1
150                  NA                  NA                99
impute_staff <- function( df, v2022, v2023, vNA ){
  
  x.2022 <- df[[ v2022 ]]
  x.2023 <- df[[ v2023 ]]
  x.NA   <- df[[ vNA   ]]
  
  na.2022 <- is.na( x.2022 )
  na.2023 <- is.na( x.2023 )
  both.na <- na.2022 & na.2023
  
  # Not applicable is "unsure"
  x.NA[ is.na( x.NA ) ] <- 0
  x.NA[ x.NA == 0 & both.na ] <- 99
  
  # impute missing 2023 values with 2022 values 
  x.2023[ na.2023 ] <- x.2022[ na.2023 ]
  v2023i <- paste0( v2023, "_imp" )
  
  df[[ v2023i ]] <- x.2023
  df[[   vNA ]] <- x.NA
  
  return(df)
}


survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_Fulltime_2022", 
                v2023="Staff_Fulltime_2023", 
                vNA="Staff_Fulltime_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_Parttime_2022", 
                v2023="Staff_Parttime_2023", 
                vNA="Staff_Parttime_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_Boardmmbr_2022", 
                v2023="Staff_Boardmmbr_2023", 
                vNA="Staff_Boardmmbr_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_RegVlntr_2022", 
                v2023="Staff_RegVlntr_2023", 
                vNA="Staff_RegVlntr_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_EpsdVltnr_2022", 
                v2023="Staff_EpsdVltnr_2023", 
                vNA="Staff_EpsdVltnr_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_AmerVlntr_2022", 
                v2023="Staff_AmerVlntr_2023", 
                vNA="Staff_AmerVlntr_NA" )

survey_df <- 
  survey_df %>% 
  impute_staff( v2022="Staff_PdCnslt_2022", 
                v2023="Staff_PdCnslt_2023", 
                vNA="Staff_PdCnslt_NA" )
Original Value Description Recode Label Recode Value Code as Missing ?
1 Yes, this question is not applicable Not Applicable 1 No
NA No, this question applies to me OK 1 No
All NA N/A response conflicts Unsure 99 Yes
# APPLY TO COLUMNS K:
COLUMNS <-  staff_qns_bool

# VALUES THAT NEED RECODING

RULES <- c(    
          
             "    1    =>>      1    ", 
             "    0    =>>      0    ", 
             "   99    =>>     99    "     )


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

# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1", "99" )
labels  <- c( "OK", "N/A", "UNSURE" )
missing <- "UNSURE"

# 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
Missing values: UNSURE

Values and labels N Percent
0 ‘OK’ 456 90 . 8
1 ‘N/A’ 40 8 . 0
99 ‘UNSURE’ 6 1 . 2

QUESTION TXT:
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

10.4.2 Reserve Questions

Original Value Description Recode Label Recode Value Code as Missing ?
1 Yes, this question is not applicable N/A 1 No
NA This question applies to me 0 OK No
All NA N/A response conflicts Unsure 99 Yes
# APPLY TO COLUMNS K:
COLUMNS <-  reserve_qns_bool

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

# did not respond to the reserve questions
no.resp <- is.na( survey_df$Reserves_Est )
survey_df$Reserves_NA_X[ no.resp ] <-  99
    

# VALUES THAT NEED RECODING

RULES <- c(    
          
             "    1    =>>     1   ", 
             "    0    =>>     0   "   )


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


# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1", "99" )
labels  <- c( "OK", "N/A", "Did Not Answer" )
missing <- "99"

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

Example:

Reserves_NA_X‘TYPE: boolean’

“Estimated total operating cash and unrestricted liquid assets in reserve is not applicable”

Storage mode: character
Measurement: nominal
Missing values: 99

Values and labels N Valid Total
0 ‘OK’ 355 95 . 9 70 . 7
1 ‘N/A’ 15 4 . 1 3 . 0
99 M ‘Did Not Answer’ 132 26 . 3

QUESTION TXT:
Approximately how much total operating cash and unrestricted liquid assets in reserve did you… - Select here if your organization does not have a reserve fund - Total operating cash and unrestricted liquid assets in reserve - C

10.4.3 People Served Questions

Original Value Description Recode Label Recode Value Code as Missing ?
1 Yes, this question is not applicable N/A 1 No
NA This question applies to me 0 OK No
All NA N/A response conflicts Unsure 99 Yes
# APPLY TO COLUMNS K:
COLUMNS <-  people_served_qns_bool


# ALL RESPONSES NA IN GROUP:
# indication that the question
# was skipped by the respondent

people_qns <- c( "PplSrv_NumServed", "PplSrv_NumWait" )

row.id <- apply( survey_df[ people_qns ], 
                 MARGIN = 1, 
                 FUN = function(x){ all(is.na(x)) } ) 


# NA means "no"

na_to_zero <- function(x){
  x[ is.na(x) ] <- 0
  return(x)
}

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

# if they do not respond "yes" 
# to at least one question then
# assume they skipped them all

zero_to_99 <- function( x, rowid ){
  x[ rowid ] <- 99
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( zero_to_99, row.id )

    

# VALUES THAT NEED RECODING

RULES <- c(    "    1    =>>     1    ", 
               "    0    =>>     0    ",
               "   NA    =>>   _NA_   "      )


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


# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( "0", "1", "99", "_NA_" )
labels  <- c( "OK", "N/A", "No response", "No response" )
missing <- c( "99", "_NA_" )

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

Example:

PplSrv_NumServed_NA_X‘TYPE: boolean’

“Number of people served not applicable”

Storage mode: character
Measurement: nominal
Missing values: 99, NA

Values and labels N Valid Total
0 ‘OK’ 444 99 . 6 88 . 4
1 ‘N/A’ 2 0 . 4 0 . 4
99 M ‘No response’ 56 11 . 2

QUESTION TXT:
Approximately how many people do you estimate your organization served and… - Check here if not applicable for your organization - Number of People Served - N/A

11 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.

11.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.

11.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(    
          
             "   0    =>>     0   ",
             "   1    =>>     1   ", 
             "  98    =>>     2   "     )


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

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

# 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: NA

Values and labels N Valid Total
0 ‘Decrease’ 126 25 . 2 25 . 1
1 ‘Unchanged’ 7 1 . 4 1 . 4
2 ‘Increase’ 367 73 . 4 73 . 1
NA M 2 0 . 4

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

11.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

row.id <- apply( survey_df[ COLUMNS ], 
                 MARGIN = 1, 
                 FUN = function(x) all(is.na(x)) )

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   ",
     "                                           98    =>>     0   ",
     "                                           99    =>>     X   "  )
 
rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]


all_na <- function( x, rowid ){
  x[ rowid ] <- NA
  return(x)
}

survey_df[ COLUMNS ] <- 
  survey_df[ COLUMNS ] %>% 
  lapply( all_na, row.id )


# MEMISC LABELS AND MISSING VALUE CODES 
values  <- c( 5, 4, 3, 2, 1, 0, "X"  )
labels  <- c( "Increase Significantly", "Increase Moderately", 
              "Unchanged", "Decrease Moderately", "Decrease Significantly", 
              "Unsure", "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’ 10 2 . 2 2 . 0
1 ‘Decrease Significantly’ 62 13 . 4 12 . 4
2 ‘Decrease Moderately’ 41 8 . 9 8 . 2
3 ‘Unchanged’ 140 30 . 4 27 . 9
4 ‘Increase Moderately’ 136 29 . 5 27 . 1
5 ‘Increase Significantly’ 72 15 . 6 14 . 3
X M ‘Not Applicable’ 10 2 . 0
NA M 31 6 . 2

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

12 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.

12.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    =>>     0   "    )

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

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

# 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: NA

Values and labels N Valid Total
0 ‘Not Used’ 31 6 . 2 6 . 2
1 ‘Not At All Important’ 111 22 . 2 22 . 1
2 ‘Not Very Important’ 134 26 . 7 26 . 7
3 ‘Somewhat Important’ 149 29 . 7 29 . 7
4 ‘Very Important’ 54 10 . 8 10 . 8
5 ‘Essential’ 22 4 . 4 4 . 4
NA M 1 0 . 2

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

12.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 1 No
Very important, we depend on individual donations for a wide range of activities, but not all Very Important 2 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 4 No
Not at all important, we could carry out our mission and goals without donations from individuals Fifth Most Important Not At All Important 5 No
We do not receive donations from individuals Sixth Most Important Not Used 6 No
-99 Incomplete Incomplete 0 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  =>>  1  ",
  "     Very important, we depend on individual donations for a wide range of activities, but not all  =>>  2  ",
  "                           Important, we depend on individual donations for several key activities  =>>  3  ",
  "           Not very important, we depend on individual donations for only non-essential activities  =>>  4  ",
  " Not at all important, we could carry out our mission and goals without donations from individuals  =>>  5  ",
  "                                                      We do not receive donations from individuals  =>>  6  ",
  "                                                                                               -99  =>>  0  "  )


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

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

# 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: NA

Values and labels N Valid Total
1 ‘Essential’ 125 25 . 0 24 . 9
2 ‘Very Important’ 218 43 . 5 43 . 4
3 ‘Somewhat Important’ 97 19 . 4 19 . 3
4 ‘Not Very Important’ 33 6 . 6 6 . 6
5 ‘Not At All Important’ 16 3 . 2 3 . 2
6 ‘Not Used’ 0 0 . 0 0 . 0
99 ‘99’ 12 2 . 4 2 . 4
NA M 1 0 . 2

QUESTION TXT:
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?

13 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 ?
More Often Than Not Most Frequent Most of the time 5 No
Frequently Second Most Frequent Frequently 4 No
Occasionally Third Most Frequent Occasionally 3 No
Rarely Fourth Most Frequent Rarely 2 No
Never Fifth Most Frequent Occasionally 1 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(    

     "    More Often Than Not    =>>     5   ",
     "             Frequently    =>>     4   ",
     "           Occasionally    =>>     3   ",
     "                 Rarely    =>>     2   ",
     "                  Never    =>>     1   "   )
     
rules <- parse_rules( RULES )          
pattern <- rules[[ "pattern" ]]
replace <- rules[[ "replace" ]]

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

# 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: NA

Values and labels N Valid Total
1 ‘Never’ 139 31 . 7 27 . 7
2 ‘Rarely’ 60 13 . 7 12 . 0
3 ‘Occasionally’ 119 27 . 1 23 . 7
4 ‘Frequently’ 91 20 . 7 18 . 1
5 ‘Most of the time’ 30 6 . 8 6 . 0
NA M 63 12 . 5

QUESTION TXT:
During the last two years (2022-2023), 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

14 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_2022‘TYPE: integer’

“Number of full time staff”

Storage mode: double
Measurement: interval
Missing values: Inf

Values and labels N Percent
NA M 43 8 . 6

Min: 0 . 000
Max: 3800 . 000
Mean: 20 . 950
Std.Dev.: 179 . 420

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

15 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
NA M 35 7 . 0

Min: 0 . 000
Max: 1000000 . 000
Mean: 6178 . 546
Std.Dev.: 47376 . 540

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

16 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_2022 'TYPE: text'

   "Description of other staff"

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

   Storage mode: character
   Measurement: nominal

   Min:                  "1099 artists"
   Max: "teaching artists & conductors"

   QUESTION TXT:
       How many (paid and unpaid) people in your organization will have
       worke... - 2022 - Other (please specify): - Text

Example:

Staff_Other_Text_2022‘TYPE: text’

“Description of other staff”

Storage mode: character
Measurement: nominal

Min: “1099 artists”
Max: “teaching artists & conductors”

QUESTION TXT:
How many (paid and unpaid) people in your organization will have worke… - 2022 - Other (please specify): - Text