Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Repeat triple nested lists based on length of matching column in R

I would like to duplicate/repeat triple nested lists based on the number of rows matching the same name in a data frame.

Here is a triple nested list:

list.A <- list(a = c(1,2,5,6), b = c(2,4,6,5), c = c(2,4,2,5))
list.B <- list(a = c(7,7,7,7), b = c(8,8,8,8), c = c(9,9,9,9))
weights <- list(list.A, list.B)
names(weights) <- c("list.A", "list.B")

list.A <- list(a = c(2,2,2,2), b = c(3,3,3,3), c = c(4,4,4,4))
list.B <- list(a = c(5,5,5,5), b = c(6,6,6,6), c = c(7,7,7,7))
scores <- list(list.A, list.B)
names(scores) <- c("list.A", "list.B")

megalist <- list(weights, scores)
names(megalist) <- c("weights", "scores")
megalist

> megalist
$weights
$weights$list.A
$weights$list.A$a
[1] 1 2 5 6

$weights$list.A$b
[1] 2 4 6 5

$weights$list.A$c
[1] 2 4 2 5


$weights$list.B
$weights$list.B$a
[1] 7 7 7 7

$weights$list.B$b
[1] 8 8 8 8

$weights$list.B$c
[1] 9 9 9 9



$scores
$scores$list.A
$scores$list.A$a
[1] 2 2 2 2

$scores$list.A$b
[1] 3 3 3 3

$scores$list.A$c
[1] 4 4 4 4


$scores$list.B
$scores$list.B$a
[1] 5 5 5 5

$scores$list.B$b
[1] 6 6 6 6

$scores$list.B$c
[1] 7 7 7 7

Here is my dataframe that I want to use to dictate the number of repeated lists:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

mydf <- as.data.frame(c("a", "a", "a", "b", "b", "c"))
colnames(mydf) <- "Freq"

> mydf
  Freq
1    a
2    a
3    a
4    b
5    b
6    c

I would like this output where from megalist[["list.A"]] list a is repeated 3 times because it has 3 rows in mydf, b is repeated 2 times because it has the next 2 rows in mydf, and c is repeated 1 time because it has the next 1 row in mydf:

> megalist
$weights
$weights$list.A
$weights$list.A$a
[1] 1 2 5 6

$weights$list.A$a
[1] 1 2 5 6

$weights$list.A$a
[1] 1 2 5 6

$weights$list.A$b
[1] 2 4 6 5

$weights$list.A$b
[1] 2 4 6 5

$weights$list.A$c
[1] 2 4 2 5


$weights$list.B
$weights$list.B$a
[1] 7 7 7 7

$weights$list.B$b
[1] 8 8 8 8

$weights$list.B$c
[1] 9 9 9 9



$scores
$scores$list.A
$scores$list.A$a
[1] 2 2 2 2

$scores$list.A$a
[1] 2 2 2 2

$scores$list.A$a
[1] 2 2 2 2

$scores$list.A$b
[1] 3 3 3 3

$scores$list.A$b
[1] 3 3 3 3

$scores$list.A$c
[1] 4 4 4 4


$scores$list.B
$scores$list.B$a
[1] 5 5 5 5

$scores$list.B$b
[1] 6 6 6 6

$scores$list.B$c
[1] 7 7 7 7

I have tried:

megalist.repeated <- lapply(megalist, function(x, new) {
  x[["list.A"]][new]
}, new = mydf$Freq)

but this gets rid of list.B, and I want to keep everything else the same and change only list.A.

I have also tried:

megalist.repeated <- lapply(megalist, function(x, y) 
  if(x[["y"]]=="list.A") 
    lapply(y, function (y, new) {
      y[new]
    }, new = mydf$Freq
  ) else y)

but my if statement returns a length of zero.

>Solution :

Loop over the nested list with lapply, then extract ([[) the ‘list.A’ element with a lambda function, use the mydf$Freq to replicate the named inner list of list.A, assign (<-) back to the same element to update, and return the whole object x

megalist2 <- lapply(megalist, \(x) {
    x[["list.A"]] <- x[["list.A"]][mydf$Freq]
     x})

-checking the structure of old vs new object

> str(megalist2)
List of 2
 $ weights:List of 2
  ..$ list.A:List of 6
  .. ..$ a: num [1:4] 1 2 5 6
  .. ..$ a: num [1:4] 1 2 5 6
  .. ..$ a: num [1:4] 1 2 5 6
  .. ..$ b: num [1:4] 2 4 6 5
  .. ..$ b: num [1:4] 2 4 6 5
  .. ..$ c: num [1:4] 2 4 2 5
  ..$ list.B:List of 3
  .. ..$ a: num [1:4] 7 7 7 7
  .. ..$ b: num [1:4] 8 8 8 8
  .. ..$ c: num [1:4] 9 9 9 9
 $ scores :List of 2
  ..$ list.A:List of 6
  .. ..$ a: num [1:4] 2 2 2 2
  .. ..$ a: num [1:4] 2 2 2 2
  .. ..$ a: num [1:4] 2 2 2 2
  .. ..$ b: num [1:4] 3 3 3 3
  .. ..$ b: num [1:4] 3 3 3 3
  .. ..$ c: num [1:4] 4 4 4 4
  ..$ list.B:List of 3
  .. ..$ a: num [1:4] 5 5 5 5
  .. ..$ b: num [1:4] 6 6 6 6
  .. ..$ c: num [1:4] 7 7 7 7
> str(megalist)
List of 2
 $ weights:List of 2
  ..$ list.A:List of 3
  .. ..$ a: num [1:4] 1 2 5 6
  .. ..$ b: num [1:4] 2 4 6 5
  .. ..$ c: num [1:4] 2 4 2 5
  ..$ list.B:List of 3
  .. ..$ a: num [1:4] 7 7 7 7
  .. ..$ b: num [1:4] 8 8 8 8
  .. ..$ c: num [1:4] 9 9 9 9
 $ scores :List of 2
  ..$ list.A:List of 3
  .. ..$ a: num [1:4] 2 2 2 2
  .. ..$ b: num [1:4] 3 3 3 3
  .. ..$ c: num [1:4] 4 4 4 4
  ..$ list.B:List of 3
  .. ..$ a: num [1:4] 5 5 5 5
  .. ..$ b: num [1:4] 6 6 6 6
  .. ..$ c: num [1:4] 7 7 7 7
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading