Home > Software engineering >  How do I make the number of two-sided formulas in case_when depend on the number of arguments?
How do I make the number of two-sided formulas in case_when depend on the number of arguments?

Time:02-24

I have two functions that I want to generalize below. I would like the generic function be called likert_score.

a is a vector of characters. length(a) should be the number of two-sided formulas before the formula TRUE ~ x. How can I make this function or a reprex?

likert_score_4 <- function(x, a){
  a_seq <- seq_along(a) %>% as.character
  
  case_when(
    x == a[1] ~ a_seq[1],
    x == a[2] ~ a_seq[2],
    x == a[3] ~ a_seq[3],
    x == a[4] ~ a_seq[4],
    TRUE ~ x
  )
}


likert_score_5 <- function(x, a){
  case_when(
    x == a[1] ~ a_seq[1],
    x == a[2] ~ a_seq[2],
    x == a[3] ~ a_seq[3],
    x == a[4] ~ a_seq[4],
    x == a[5] ~ a_seq[5],
    TRUE ~ x
  )
}

CodePudding user response:

likert_score <- function(x, a){
   recode(x, !!!setNames(as.character(seq_along(a)), a))
}

CodePudding user response:

  • match(x,a) finds the index of the matching element in a for each value of x, NA if there is no match
  • the ifelse() replaces non-matching values with the corresponding values of x (could also say x[!is.na(m)] <- na.omit(m))
  • then we use as.character() in case we need it
likert_score <- function(x,a ) {
  m <- match(x, a)
  as.character(ifelse(is.na(m), x, m))
}
a <- LETTERS[1:4]
set.seed(101)
x <- sample(LETTERS[1:5], size = 20, replace = TRUE)
identical(likert_score_4(x,a), likert_score(x,a))  ## TRUE

or if you want it inscrutable and pipe-y:

match(x,a) %>% ifelse(test = is.na(.), yes = x) %>% as.character()
  • Related