Search code examples
rlistvector

How to pour values from a R vector into a list object without regarding the list structure including the levels of nesting and names used in the list?


Suppose we have a raw list object list_tmp, with varying levels of nesting, that looks like the below (at the bottom of the post is code for list_tmp.):

> list_tmp
$clinic
$clinic$trial
$clinic$trial$patient
     A B
[1,] 0 0
[2,] 0 0


$clinic$result
     C
[1,] 0
[2,] 0


$test
     D
[1,] 0
[2,] 0

How can vector values be "poured into" the list object, in the direction rows-columns, without regarding the sublist names or nesting levels? Filling occurs until the earlier of exhausting the vector elements, or until reaching the end of the list. In the full code this is intended for, the number of vector elements will always equal the number of "cells" in the list.

For example, if we have vector vec <- (1,2,3,4,5,6,7,8), sequentially pouring those vector values into list_tmp would result in the following:

> list_tmp
$clinic
$clinic$trial
$clinic$trial$patient
     A B
[1,] 1 3
[2,] 2 4


$clinic$result
     C
[1,] 5
[2,] 6


$test
     D
[1,] 7
[2,] 8

Code for list_tmp:

list_tmp <- list(
  clinic = list(
    trial = list(
      patient = matrix(0, nrow = 2, ncol = 2, dimnames = list(NULL, c("A", "B")))
    ),
    result = matrix(0, nrow = 2, ncol = 1, dimnames = list(NULL, c("C")))
  ),
  test = matrix(0, nrow = 2, ncol = 1, dimnames = list(NULL, c("D")))
)

Solution

  • Easily done with relisting:

    a <- unlist(as.relistable(list_tmp))
    a[seq_along(vec)] <- vec
    unclass(relist(a))
    
    $clinic
    $clinic$trial
    $clinic$trial$patient
         A B
    [1,] 1 3
    [2,] 2 4
    
    
    $clinic$result
         C
    [1,] 5
    [2,] 6
    
    
    $test
         D
    [1,] 7
    [2,] 8
       
    

    vec <- c(1,2,3,4,5,6,7,8)