## 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"
```