Home > Software design >  Make custom function handle nested lists
Make custom function handle nested lists

Time:05-25

Reproducible example: 2 nested lists, as defined below, with their respective colnames

nested list 1 containing 2 dfs with [2,3] and [3,5] dimensions

list1 <- list(as.data.frame(matrix(nrow = 2, ncol = 3)), as.data.frame(matrix(nrow = 3, ncol = 5)))
colnames(list1[[1]]) <- c("M1", "M2", "M3")
colnames(list1[[2]]) <- c("X1", "X2", "X3", "X4", "X5")
list1

nested list 2 containing 2 dfs with [3,4] and [2,5] dimensions

list2 <- list(as.data.frame(matrix(nrow = 3, ncol = 4)), as.data.frame(matrix(nrow = 2, ncol = 5)))
colnames(list2[[1]]) <- c("L1", "L2", "L3", "L4")
colnames(list2[[2]]) <- c("Z1", "Z2", "Z3", "Z4", "Z5")
list2

Custom function that takes colnames of each df and produces a string (e.g. "F1 =~ M1 M2 M3")

foo_gen_CFA_syn = function(data){ # arg: data = individual list with nested dataframes  
    
    syntax_of_X_CFA_models <- vector(mode = "character", length = length(data))

    for(i in 1:length(data)){
        syntax_of_X_CFA_models[i] <- paste0("F", sep = "", i, sep = " =~ ", paste(colnames(data[[i]]), collapse = "   "))
    }
    
    return(syntax_of_X_CFA_models)
}

This works fine with list 1 and list 2 individually and produces the following output

> foo_gen_CFA_syn(data = list1)
[1] "F1 =~ M1   M2   M3"           "F2 =~ X1   X2   X3   X4   X5"
> foo_gen_CFA_syn(data = list2)
[1] "F1 =~ L1   L2   L3   L4"      "F2 =~ Z1   Z2   Z3   Z4   Z5"

Also works fine with list 1 and list 2 together

foo_gen_CFA_syn(data = c(list1, list2))
    [1] "F1 =~ M1   M2   M3"           "F2 =~ X1   X2   X3   X4   X5" "F3 =~ L1   L2   L3   L4"     
    [4] "F4 =~ Z1   Z2   Z3   Z4   Z5"

Problem: instead of feeding a vector of lists, I want to specify a nested list that will contain all of the lists. Something like the below

list3 <- list(list1, list2)

but that is where it breaks and produces wrong output

> foo_gen_CFA_syn(data = list3)
[1] "F1 =~ " "F2 =~ "

CodePudding user response:

Add unlist(data, recursive = FALSE) to the function:

foo_gen_CFA_syn = function(data){ # arg: data = individual list with nested dataframes  
 
  data <- unlist(data, recursive = FALSE)
   
  syntax_of_X_CFA_models <- vector(mode = "character", length = length(data))
  for(i in 1:length(data)){
    syntax_of_X_CFA_models[i] <- paste0("F", sep = "", i, sep = " =~ ", paste(colnames(data[[i]]), collapse = "   "))
  }
  
  return(syntax_of_X_CFA_models)
}

Output:

foo_gen_CFA_syn(list3)
#"F1 =~ M1   M2   M3"           "F2 =~ X1   X2   X3   X4   X5" "F3 =~ L1   L2   L3   L4"      "F4 =~ Z1   Z2   Z3   Z4   Z5"
  • Related