2
votes

I currently have long format data

# Input
library(dplyr)
library(tidyr)

tibble(
    x = c(1,1,2,2), 
    y = c("A", "B", "C", "D")
) 

I want to widen the data to look like this:

# Desired Output
tibble(
    x = c(1,2), 
    x_1 = c("A", "C"), 
    x_2 = c("B", "D")
) 

But this isn't a typical tidyr::spread() because my column names are not becoming cell values. So while this seems simple, I'm stumped.

3
Answers here might helpcamille

3 Answers

1
votes

from tidyr 1.0.0 you can do the following :

library(tidyr)

df <- tibble(
  x = c(1,1,2,2), 
  y = c("A", "B", "C", "D")
) 

chop(df,y) %>% unnest_wider(y)
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> # A tibble: 2 x 3
#>       x ...1  ...2 
#>   <dbl> <chr> <chr>
#> 1     1 A     B    
#> 2     2 C     D

Created on 2019-09-14 by the reprex package (v0.3.0)

Add parameter names_repair = ~sub("..." , "x_", ., fixed=TRUE) to the unnest_wider call to get the names you gave in your question.

3
votes
library(data.table)

dcast(df, x ~ paste0('x_', rowid(x)))
#   x x_1 x_2
# 1 1   A   B
# 2 2   C   D
2
votes

An option would be to create a sequence column by group and then do the spread

library(dplyr)
library(tidyr)
library(stringr)
tbl1 %>% 
    group_by(x) %>% 
    group_by(x1 = str_c('x_', row_number())) %>% 
    # or using paste0 from base R (as @d.b commented)
    # group_by(x1 = paste0('x_', row_number())) %>%
    spread(x1, y)
# A tibble: 2 x 3
#      x x_1   x_2  
#  <dbl> <chr> <chr>
#1     1 A     B    
#2     2 C     D    

Or in base R

unstack(df, y~ ave(x, x, FUN = seq_along))