Home > OS >  tidy syntax for matrix to tibble by index?
tidy syntax for matrix to tibble by index?

Time:10-13

I have a matrix foo and want to create a data.frame or tibble like bar with the data in a long format with the indices as columns. What's a simple way to do this in the tidyverse?

z <- c(1,8,6,4,7,3,2,4,7)
foo <- matrix(z,3,3)
bar <- expand.grid(j=1:3,i=1:3)
bar$z <- z
foo
bar

CodePudding user response:

Here are two ways.
The first is in fact a base R solution, just change magrittr's pipe for R's native pipe operator |>.
The second is a tidyverse solution which I find too complicated.

suppressPackageStartupMessages(
  library(tidyverse)
)

z <- c(1,8,6,4,7,3,2,4,7)
foo <- matrix(z,3,3)
bar <- expand.grid(j=1:3,i=1:3)
bar$z <- z

cbind(
  i = foo %>% row() %>% c(),
  j = foo %>% col() %>% c(),
  z = foo %>% c()
) %>%
  as.data.frame()
#>   i j z
#> 1 1 1 1
#> 2 2 1 8
#> 3 3 1 6
#> 4 1 2 4
#> 5 2 2 7
#> 6 3 2 3
#> 7 1 3 2
#> 8 2 3 4
#> 9 3 3 7


foo %>%
  t() %>%
  as.data.frame() %>%
  pivot_longer(everything(), values_to = "z") %>%
  mutate(i = c(row(foo)), j = c(col(foo))) %>%
  select(-name) %>%
  relocate(z, .after = j)
#> # A tibble: 9 × 3
#>       i     j     z
#>   <int> <int> <dbl>
#> 1     1     1     1
#> 2     2     1     8
#> 3     3     1     6
#> 4     1     2     4
#> 5     2     2     7
#> 6     3     2     3
#> 7     1     3     2
#> 8     2     3     4
#> 9     3     3     7

Created on 2022-10-12 with reprex v2.0.2

CodePudding user response:

Another base R method would be to take advantage of as.table and as.data.frame

as.data.frame(lapply(as.data.frame(as.table(foo)), as.numeric), 
              col.names = c("row", "col", "val"))
#>   row col val
#> 1   1   1   1
#> 2   2   1   8
#> 3   3   1   6
#> 4   1   2   4
#> 5   2   2   7
#> 6   3   2   3
#> 7   1   3   2
#> 8   2   3   4
#> 9   3   3   7
  • Related