Home > OS >  error in assign `dimnames` to all matrices in a list
error in assign `dimnames` to all matrices in a list

Time:03-25

I used the solution in this thread assign dimnames to a list of matrices in R but I didn't get what I need.

I have a list of 4 matrices that I wanted to name their columns and rows the same.

A = list(a = matrix(1:4, 2), b = matrix(2:5, 2))

G = list(a = matrix(10:13, 2), b = matrix(5:8, 2))

M_1 = list(a = matrix(10:13, 2), b = matrix(5:8, 2))

M_2 = list(a = matrix(2:5, 2), b = matrix(5:8, 2))

dlist4 <- tibble::lst(A, G, M_1, M_2)
Map(function(x) {dimnames(x) <- list(c("seed","plant"), c("seed","plant")); x}, dlist4)

and

lapply(dlist4, function(x) {dimnames(x) = list(c("seed","plant"), c("seed","plant")); x})

returned the same error: Error in dimnames(x) <- list(c("seed", "plant"), c("seed", "plant")) : 'dimnames' applied to non-array

I tried the loop here R: change column names of every matrix in a list, too but it didn't work.

for(i in seq_along(dlist4)) {
        dimnames(dlist4[[i]]) <- list(c("seed","plant"), c("seed","plant"))
 }

Error in dimnames(dlist4[[i]]) <- list(c("seed", "plant"), c("seed", "plant")) : 'dimnames' applied to non-array

CodePudding user response:

You don't have a matrix inside your main list, you have another set of lists - see lapply(dlist4, class). So it's not 4 matrices, it's 4 sets of two matrices, each in a list.

In this instance, you need to recursively go down until you stop hitting lists, which means rapply might be handy:

rapply(dlist4, function(x) {dimnames(x) <- rep(list(c("seed","plant")), 2); x}, how="list")
#$A
#$A$a
#      seed plant
#seed     1     3
#plant    2     4
#
#$A$b
#      seed plant
#seed     2     4
#plant    3     5
#
#
#$G
#$G$a
#      seed plant
#seed    10    12
#plant   11    13
#...

CodePudding user response:

Since you don't have a list of matrices, but a list of lists of matrices, you will have to use a nested lapply() or a nested loop:

dlist4 <- tibble::lst(A, G, M_1, M_2)

lapply(dlist4, function(x) {lapply(x, `dimnames<-`, rep(list(c("seed", "plant")),2))})
#> $A
#> $A$a
#>       seed plant
#> seed     1     3
#> plant    2     4
#> 
#> $A$b
#>       seed plant
#> seed     2     4
#> plant    3     5
#> 
#> 
#> $G
#> $G$a
#>       seed plant
#> seed    10    12
#> plant   11    13
#> 
#> $G$b
#>       seed plant
#> seed     5     7
#> plant    6     8
#> 
#> 
#> $M_1
#> $M_1$a
#>       seed plant
#> seed    10    12
#> plant   11    13
#> 
#> $M_1$b
#>       seed plant
#> seed     5     7
#> plant    6     8
#> 
#> 
#> $M_2
#> $M_2$a
#>       seed plant
#> seed     2     4
#> plant    3     5
#> 
#> $M_2$b
#>       seed plant
#> seed     5     7
#> plant    6     8

Alternatively, you could also use purrr::map_depth() which is design specifically for nested lists:

purrr::map_depth(dlist4, 
                 2, 
                 `dimnames<-`, 
                 rep(list(c("seed", "plant")),2)
                 )

Created on 2022-03-25 by the reprex package (v2.0.1)

  • Related