Search code examples
rlistsapply

How to make lapply/sapply output a list in R?


I am trying to figure out how to create a list with lapply/sapply. From the documentation I gather this is possible using sapply with USE.NAMES = TRUE, but my example is not working.

I need to str-replace variable names to look them up in the input list where spaces are replaced with dashes. I have no direct control over this list (it is the input reactive element in an R shiny app)

input <- list("Subject-Identifier" = c("1022", "1023", "1024"),
              "Next-Screening" = c("A", "B", "C"))

variables <- c("Subject Identifier", "Next Screening")


### I tried these:
res <- lapply(variables, function(x){
  input[[stringr::str_replace_all(x, " ", "-")]]
})

[[1]]
[1] "1022" "1023" "1024"

[[2]]
[1] "A" "B" "C"


res <- sapply(variables, function(x){
  input[[stringr::str_replace_all(x, " ", "-")]]
}, USE.NAMES = TRUE)

     Subject Identifier Next Screening
[1,] "1022"             "A"           
[2,] "1023"             "B"           
[3,] "1024"             "C"           


### I want this:

$`Subject Identifier`
[1] "1022" "1023" "1024"

$`Next Screening`
[1] "A" "B" "C"


Solution

  • We can pass a named vector and lapply returns the named list (which can be done either before or afterwards)

    lapply(setNames(variables, variables), function(x){
      input[[stringr::str_replace_all(x, " ", "-")]]})
    

    -output

    $`Subject Identifier`
    [1] "1022" "1023" "1024"
    
    $`Next Screening`
    [1] "A" "B" "C"
    

    Regarding the second case, sapply by default use simplify = TRUE, which can be changed to FALSE and then it will return the expected

    sapply(variables, function(x){
      input[[stringr::str_replace_all(x, " ", "-")]]
    }, USE.NAMES = TRUE, simplify = FALSE)
    

    -output

    $`Subject Identifier`
    [1] "1022" "1023" "1024"
    
    $`Next Screening`
    [1] "A" "B" "C"