Search code examples
rtidyrspread

Transpose Rows in batches to Columns in R


My data.frame df looks like this:

A 1  
A 2  
A 5  
B 2  
B 3  
B 4  
C 3  
C 7  
C 9  

I want it to look like this:

A B C  
1 2 3  
2 3 7  
5 4 9  

I have tried spread() but probably not in the right way. Any ideas?


Solution

  • We can use unstack from base R

    unstack(df1, col2 ~ col1)
    #  A B C
    #1 1 2 3
    #2 2 3 7
    #3 5 4 9
    

    Or with split

    data.frame(split(df1$col2, df1$col1))
    

    Or if we use spread or pivot_wider, make sure to create a sequence column

    library(dplyr)
    library(tidyr)
    df1 %>%
      group_by(col1) %>%
      mutate(rn = row_number()) %>%
      ungroup %>%
      pivot_wider(names_from = col1, values_from = col2) %>%
      # or use
      # spread(col1, col2) %>%
      select(-rn)
    # A tibble: 3 x 3
    #      A     B     C
    #  <int> <int> <int>
    #1     1     2     3
    #2     2     3     7
    #3     5     4     9
    

    Or using dcast

    library(data.table)
    dcast(setDT(df1), rowid(col1) ~ col1)[, .(A, B, C)]
    

    data

    df1 <- structure(list(col1 = c("A", "A", "A", "B", "B", "B", "C", "C", 
    "C"), col2 = c(1L, 2L, 5L, 2L, 3L, 4L, 3L, 7L, 9L)),
       class = "data.frame", row.names = c(NA, 
    -9L))