How to create a list such that each element of the list is the row name of a dataframe based on a matrix in R

How to create a list such that each element of the list is the row name of a dataframe based on a matrix in R

Problem Description:

I have an example dataframe s1

s1=data.frame(c1=c("red","green","blue","yellow","orange","black","white"),col1=c("car1","car2","car3","car4","car5","car6","car7"))
s1=s1 %>% remove_rownames %>% column_to_rownames(var="c1")

There is only one column-col1 and the row names are red,green, blue and so on.

       col1
red    car1
green  car2
blue   car3
yellow car4
orange car5
black  car6
white  car7

I also have a matrix containg only 1′ and 0’s

m1= matrix(c(1,0,0,1,0),nrow =7, ncol =3, byrow = TRUE) 
     [,1] [,2] [,3]
[1,]    1    0    0
[2,]    1    0    1
[3,]    0    0    1
[4,]    0    1    0
[5,]    0    1    0
[6,]    1    0    0
[7,]    1    0    1

I want to create a list such that each element of the list contains the row names of s1, only if the corresponding element of the matrix is 1. I need to iterate this over all columns of the matrix.

the output should looks something like this

l1=list(c("red","green","black","white"),c("yellow","orange"),c("green","blue","white"))

I tried using this code but i was unable to apply it to every column

row.names(s1)[which(m1[,1]==1)]

Note that both the actual dataframe and matrix are much bigger.
Thank you!

Solution – 1

Split by columns of ‘m1’ with asplit on a logical matrix and use the index for subsetting the rownames of ‘s1’

lapply(asplit(m1 == 1, 2), function(x) row.names(s1)[x])

-output

[[1]]
[1] "red"   "green" "black" "white"

[[2]]
[1] "yellow" "orange"

[[3]]
[1] "green" "blue"  "white"

Or use apply with MARGIN=2 to loop over the columns and subset

apply(m1==1, 2, function(x) row.names(s1)[x])

Solution – 2

A more primitive and involved solution:

l1 <- ifelse(m1==1, rownames(s1), '') %>% 
  t() %>%
  split(seq(nrow(.))) %>%
  lapply((x){x[x!='']})

l1

$`1`
[1] "red"   "green" "black" "white"

$`2`
[1] "yellow" "orange"

$`3`
[1] "green" "blue"  "white"
Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject