How to unnest a "list" in a martix?

58 Views Asked by At

I have a large matrix where the rownames are sample ID and the only column contains a list of information, ex: c("xyz","abc","def" [...])

and I'd like to expand this information for each sample ID so that the new matrix would read:

rownames column1
SampleID xyz
SampleID abc
SampleID def

Would a function like tidyr's unnest() be appropriate?

2

There are 2 best solutions below

0
ThomasIsCoding On BEST ANSWER

You can try

data.frame(
  rownames = rep(row.names(mat), lengths(mat)),
  column1 = unlist(mat)
)

which gives

   rownames    column1
1         A 0.89669720
2         A 0.26550866
3         A 0.37212390
4         A 0.57285336
5         B 0.90820779
6         B 0.20168193
7         B 0.89838968
8         B 0.94467527
9         C 0.66079779
10        C 0.62911404
11        C 0.06178627
12        C 0.20597457

Or, you can use unnest like below

as.data.frame(mat) %>%
  rownames_to_column() %>%
  unnest(V1)

which gives

   rowname V1[,1]
   <chr>    <dbl>
 1 A       0.897
 2 A       0.266 
 3 A       0.372
 4 A       0.573
 5 B       0.908
 6 B       0.202
 7 B       0.898
 8 B       0.945
 9 C       0.661
10 C       0.629
11 C       0.0618
12 C       0.206

data

set.seed(0)
mat <- `rownames<-`(as.matrix(replicate(3, matrix(runif(4), 4), FALSE)), LETTERS[1:3])

> str(mat)
List of 3
 $ : num [1:4, 1] 0.897 0.266 0.372 0.573
 $ : num [1:4, 1] 0.908 0.202 0.898 0.945
 $ : num [1:4, 1] 0.6608 0.6291 0.0618 0.206
 - attr(*, "dim")= int [1:2] 3 1
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:3] "A" "B" "C"
  ..$ : NULL
0
Jake On

I generated a simplified matrix like what you have described:

matrix <- c(ID1 = "xyz", ID2 = "abc", ID3 = "def") %>% as.matrix()

    [,1] 
ID1 "xyz"
ID2 "abc"
ID3 "def"

One simple solution would be to cbind the rownames to the matrix values themselves

new.matrix <- cbind(rownames(matrix), matrix)

    [,1]  [,2] 
ID1 "ID1" "xyz"
ID2 "ID2" "abc"
ID3 "ID3" "def"

If you'd like to rename the columns, you can do so easily after converting to a data.frame:

new.matrix <- as.data.frame(cbind(rownames(matrix), matrix))
names(new.matrix) <- c("SampleID", "OtherInfo") 

    SampleID OtherInfo
ID1      ID1       xyz
ID2      ID2       abc
ID3      ID3       def