Skip to contents

Overview of hespeR S7 Classes

The hespeR package provides a set of S7 classes to structure and validate incoming survey data. Why so restrictive? Restricting to these classes ensures that only valid operations are performed, prevents accidental misuse, and allows for the development of reusable and readable methods, towards semi-automated reports. This design makes it easier to extend functionality through methods if needed.

This said, helper functions are provided to convert from and to base R objects (e.g., data frames, lists) that will be linked to a default template of an XML Kobo tool.

Main Classes

HesperVector

Represents a single HESPER item. Main features to note are: - hesper_var: the variable name of the HESPER item to which this vector corresponds. - hesper_vals: the values for this variable. It can contain NA values if allow_missing = TRUE.

hv <- HesperVector(
  hesper_var = "hesper_food",
  hesper_vals = c(
    "no_serious_problem",
    "serious_problem",
    NA,
    "dnk",
    "pnta",
    "serious_problem"
  ),
  allow_missing = TRUE
)
hv
#> <hespeR::HesperVector>
#>  @ hesper_var   : chr "hesper_food"
#>  @ hesper_vals  : chr [1:6] "no_serious_problem" "serious_problem" NA "dnk" "pnta" ...
#>  @ allow_missing: logi TRUE
#>  @ hesper_bins  :List of 5
#>  .. $ serious_problem   : int [1:6] 0 1 NA 0 0 1
#>  .. $ no_serious_problem: int [1:6] 1 0 NA 0 0 0
#>  .. $ dnk               : int [1:6] 0 0 NA 1 0 0
#>  .. $ pnta              : int [1:6] 0 0 NA 0 1 0
#>  .. $ not_applicable    : int [1:6] 0 0 NA 0 0 0

You’ve just seen printed that there is a @hesper_bins property. A getter function adds @hesper_bins to the object, which are the binary indicators (1/0) for each possible response option. Binary variables will be useful for further analysis (faster, simpler).

To access values for instance, you can simply run hv@hesper_vals or S7::props(hv, "hesper_vals").

Note that hesper_vals and hesper_var can only take a certain set of values, otherwise an error is thrown. This is to ensure that only valid data is processed. Values are stored as functions returning character vectors.

# Variables/items
hesper_vars()
#>  [1] "hesper_drinking_water"     "hesper_food"              
#>  [3] "hesper_shelter"            "hesper_toilet"            
#>  [5] "hesper_clean"              "hesper_clean_female"      
#>  [7] "hesper_clothes_etc"        "hesper_income_livelihood" 
#>  [9] "hesper_health"             "hesper_health_care_male"  
#> [11] "hesper_health_care_female" "hesper_distress"          
#> [13] "hesper_safety"             "hesper_education"         
#> [15] "hesper_care"               "hesper_support"           
#> [17] "hesper_separation"         "hesper_displaced"         
#> [19] "hesper_information"        "hesper_aid"               
#> [21] "hesper_respect"            "hesper_movement"          
#> [23] "hesper_time"               "hesper_law"               
#> [25] "hesper_gbv"                "hesper_drug"              
#> [27] "hesper_mental_health"      "hesper_care_community"    
#> [29] "hesper_other"

# Values/options
hesper_opts()
#> [1] "serious_problem"    "no_serious_problem" "dnk"               
#> [4] "pnta"               "not_applicable"

HesperList

A list of HesperVector objects, representing a set of variables for an individual or group. It inherits the validator for each HesperVector and adds a few more checks (for instance it checks that there are no duplicated HESPER item names nor different lengths of vectors of values).

hv2 <- HesperVector(
  hesper_var = "hesper_displaced",
  hesper_vals = c(
    "no_serious_problem",
    "serious_problem",
    "no_serious_problem",
    "dnk",
    "pnta",
    "serious_problem"
  ),
  allow_missing = TRUE
)
hl <- HesperList(hesper_list = list(hv, hv2))
hl
#> <hespeR::HesperList>
#>  @ hesper_list:List of 2
#>  .. $ : <hespeR::HesperVector>
#>  ..  ..@ hesper_var   : chr "hesper_food"
#>  ..  ..@ hesper_vals  : chr [1:6] "no_serious_problem" "serious_problem" NA "dnk" ...
#>  ..  ..@ allow_missing: logi TRUE
#>  ..  ..@ hesper_bins  :List of 5
#>  .. .. .. $ serious_problem   : int [1:6] 0 1 NA 0 0 1
#>  .. .. .. $ no_serious_problem: int [1:6] 1 0 NA 0 0 0
#>  .. .. .. $ dnk               : int [1:6] 0 0 NA 1 0 0
#>  .. .. .. $ pnta              : int [1:6] 0 0 NA 0 1 0
#>  .. .. .. $ not_applicable    : int [1:6] 0 0 NA 0 0 0
#>  .. $ : <hespeR::HesperVector>
#>  ..  ..@ hesper_var   : chr "hesper_displaced"
#>  ..  ..@ hesper_vals  : chr [1:6] "no_serious_problem" "serious_problem" "no_serious_problem" "dnk" ...
#>  ..  ..@ allow_missing: logi TRUE
#>  ..  ..@ hesper_bins  :List of 5
#>  .. .. .. $ serious_problem   : int [1:6] 0 1 0 0 0 1
#>  .. .. .. $ no_serious_problem: int [1:6] 1 0 1 0 0 0
#>  .. .. .. $ dnk               : int [1:6] 0 0 0 1 0 0
#>  .. .. .. $ pnta              : int [1:6] 0 0 0 0 1 0
#>  .. .. .. $ not_applicable    : int [1:6] 0 0 0 0 0 0

SL (Skip Logic)

Often, there would be other variables collected as part of a survey, for instance demographic variables about the respondent or the household. These variables can be used to define skip logic rules, specifying when certain HESPER items should be set to missing based on the values of these other variables.

A few examples are:

  • If the person does not have children, then the 12th HESPER item about education for the children should be set to missing; or,
  • for healthcare, there are different questions depending on the gender of the respondent (e.g. access to maternal healthcare); or,
  • the 16th HESPER item about displacement from home should only be asked to those who have suffered forced displacement.

As such, there is a need for a class to define skip logic rules, specifying when values should be set to missing based on other variables.

sl_rule <- SL(
  hesper_var = "hesper_displaced",
  subset_var = "pop_group",
  subset_vals = c("host", "non_displaced")
)
sl_rule
#> <hespeR::SL>
#>  @ hesper_var : chr "hesper_displaced"
#>  @ subset_var : chr "pop_group"
#>  @ subset_vals: chr [1:2] "host" "non_displaced"

HesperListEnhanced

Eventually, the last class HesperListEnhanced extends HesperList by adding skip logic (SL).

hle <- HesperListEnhanced(
  hesper_list = hl@hesper_list,
  other_list = list(
    pop_group = c("host", "refugee", "non_displaced", "host", "refugee", "host")
  ),
  SL = list(sl_rule)
)

As such an very initial method to be used and added to the object is apply_hesper_list_sl(), which applies the skip logic rules to the HesperListEnhanced object, setting values to NA where appropriate and return the object it-self.


hle <- apply_hesper_list_sl(hle)
hle
#> <hespeR::HesperListEnhanced>
#>  @ hesper_list:List of 2
#>  .. $ hesper_food     : <hespeR::HesperVector>
#>  ..  ..@ hesper_var   : chr "hesper_food"
#>  ..  ..@ hesper_vals  : chr [1:6] "no_serious_problem" "serious_problem" NA "dnk" ...
#>  ..  ..@ allow_missing: logi TRUE
#>  ..  ..@ hesper_bins  :List of 5
#>  .. .. .. $ serious_problem   : int [1:6] 0 1 NA 0 0 1
#>  .. .. .. $ no_serious_problem: int [1:6] 1 0 NA 0 0 0
#>  .. .. .. $ dnk               : int [1:6] 0 0 NA 1 0 0
#>  .. .. .. $ pnta              : int [1:6] 0 0 NA 0 1 0
#>  .. .. .. $ not_applicable    : int [1:6] 0 0 NA 0 0 0
#>  .. $ hesper_displaced: <hespeR::HesperVector>
#>  ..  ..@ hesper_var   : chr "hesper_displaced"
#>  ..  ..@ hesper_vals  : chr [1:6] NA "serious_problem" NA NA ...
#>  ..  ..@ allow_missing: logi TRUE
#>  ..  ..@ hesper_bins  :List of 5
#>  .. .. .. $ serious_problem   : int [1:6] NA 1 NA NA 0 NA
#>  .. .. .. $ no_serious_problem: int [1:6] NA 0 NA NA 0 NA
#>  .. .. .. $ dnk               : int [1:6] NA 0 NA NA 0 NA
#>  .. .. .. $ pnta              : int [1:6] NA 0 NA NA 1 NA
#>  .. .. .. $ not_applicable    : int [1:6] NA 0 NA NA 0 NA
#>  @ SL         :List of 1
#>  .. $ : <hespeR::SL>
#>  ..  ..@ hesper_var : chr "hesper_displaced"
#>  ..  ..@ subset_var : chr "pop_group"
#>  ..  ..@ subset_vals: chr [1:2] "host" "non_displaced"
#>  @ other_list :List of 1
#>  .. $ pop_group: chr [1:6] "host" "refugee" "non_displaced" "host" ...