Skip to content

Commit 43c9484

Browse files
authored
Merge pull request #1446 from cmu-delphi/splitoptions-robust-na
[CTIS] Make `split_options` return list of character missing if all input values are `NA`
2 parents 9be617d + 2214a30 commit 43c9484

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

facebook/delphiFacebook/R/variables.R

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
#' @return list of same length, each entry of which is a vector of selected
1515
#' options
1616
split_options <- function(column) {
17-
return(strsplit(column, ",", fixed = TRUE))
17+
if ( any(!is.na(column)) ) {
18+
return(strsplit(column, ",", fixed = TRUE))
19+
} else {
20+
return(rep(list(NA_character_), length(column)))
21+
}
1822
}
1923

2024
#' Test if a specific selection is selected
@@ -648,16 +652,8 @@ code_vaccines <- function(input_data, wave) {
648652
if ( all(c("V15a", "V15b") %in% names(input_data)) ) {
649653
# introduced in Wave 11
650654
vaccine_barriers <- coalesce(input_data$V15a, input_data$V15b)
651-
652-
# If the entire column is NA, ifelse() results in a logical vector, not a
653-
# character vector, which confuses split_options; since the result should be
654-
# NA anyway
655-
vaccine_barriers <- as.character(
656-
ifelse(vaccine_barriers == "13", NA_character_, vaccine_barriers)
657-
)
658-
if (any(!is.na(vaccine_barriers))) {
659-
vaccine_barriers <- split_options(vaccine_barriers)
660-
}
655+
vaccine_barriers <- ifelse(vaccine_barriers == "13", NA_character_, vaccine_barriers)
656+
vaccine_barriers <- split_options(vaccine_barriers)
661657

662658
input_data$v_vaccine_barrier_eligible <- is_selected(vaccine_barriers, "1")
663659
input_data$v_vaccine_barrier_no_appointments <- is_selected(vaccine_barriers, "2")
@@ -677,7 +673,7 @@ code_vaccines <- function(input_data, wave) {
677673
} else if ( all(c("V15c", "V15b") %in% names(input_data)) ) {
678674
# V15c introduced in Wave 12, replacing V15a with clarified wording.
679675
vaccine_barriers <- coalesce(input_data$V15c, input_data$V15b)
680-
vaccine_barriers <- ifelse(vaccine_barriers == "13", NA, vaccine_barriers)
676+
vaccine_barriers <- ifelse(vaccine_barriers == "13", NA_character_, vaccine_barriers)
681677
vaccine_barriers <- split_options(vaccine_barriers)
682678

683679
input_data$v_vaccine_barrier_eligible <- is_selected(vaccine_barriers, "1")
@@ -769,15 +765,8 @@ code_vaccines <- function(input_data, wave) {
769765

770766
if ( "V15b" %in% names(input_data) ) {
771767
# introduced in Wave 11
772-
# If the entire column is NA, ifelse() results in a logical vector, not a
773-
# character vector, which confuses split_options; since the result should be
774-
# NA anyway
775-
vaccine_barriers <- as.character(
776-
ifelse(input_data$V15b == "13", NA, input_data$V15b)
777-
)
778-
if (any(!is.na(vaccine_barriers))) {
779-
vaccine_barriers <- split_options(vaccine_barriers)
780-
}
768+
vaccine_barriers <- ifelse(input_data$V15b == "13", NA_character_, input_data$V15b)
769+
vaccine_barriers <- split_options(vaccine_barriers)
781770

782771
input_data$v_vaccine_barrier_eligible_tried <- is_selected(vaccine_barriers, "1")
783772
input_data$v_vaccine_barrier_no_appointments_tried <- is_selected(vaccine_barriers, "2")

facebook/delphiFacebook/src/RcppExports.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
using namespace Rcpp;
77

8+
#ifdef RCPP_USE_GLOBAL_ROSTREAM
9+
Rcpp::Rostream<true>& Rcpp::Rcout = Rcpp::Rcpp_cout_get();
10+
Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
11+
#endif
12+
813
// is_selected_cpp
914
LogicalVector is_selected_cpp(List responses, String target);
1015
RcppExport SEXP _delphiFacebook_is_selected_cpp(SEXP responsesSEXP, SEXP targetSEXP) {

facebook/delphiFacebook/unit-tests/testthat/test-variables.R

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ library(testthat)
22

33
context("Testing response coding")
44

5+
test_that("split_options splits correctly", {
6+
expect_equal(split_options(c("1", "", "1,2")),
7+
list(c("1"), character(0), c("1", "2")))
8+
9+
# Input logical vector
10+
expect_equal(split_options(c(NA, NA, NA)),
11+
list(NA_character_, NA_character_, NA_character_))
12+
13+
# Input character vector
14+
expect_equal(split_options(c(NA_character_, NA_character_, NA_character_)),
15+
list(NA_character_, NA_character_, NA_character_))
16+
17+
expect_equal(split_options(c("", NA_character_, NA)),
18+
list(character(0), NA_character_, NA_character_))
19+
})
20+
521
test_that("is_selected handles selections correctly", {
622
expect_equal(is_selected(split_options(c("1", "", "1,2")), "1"),
723
c(TRUE, NA, TRUE))
@@ -18,6 +34,18 @@ test_that("is_selected handles selections correctly", {
1834
expect_equal(is_selected(split_options(c("4,54", "3,6,2,54", "5,4,45")),
1935
"54"),
2036
c(TRUE, TRUE, FALSE))
37+
38+
expect_equal(is_selected(c(NA, NA, NA), "14"),
39+
c(NA, NA, NA))
40+
41+
expect_equal(is_selected(c(NA_character_, NA_character_, NA_character_), "14"),
42+
c(NA, NA, NA))
43+
44+
expect_equal(is_selected(list(NA, NA, NA), "14"),
45+
c(NA, NA, NA))
46+
47+
expect_equal(is_selected(list(NA_character_, NA_character_, NA_character_), "14"),
48+
c(NA, NA, NA))
2149
})
2250

2351
test_that("activities items correctly coded", {

0 commit comments

Comments
 (0)