Поворот шире без создания списков или лишних строк

#r #dplyr #tidyr

#r #dplyr #tidyr

Вопрос:

У меня есть фрейм данных строковых шаблонов, который в настоящее время находится в длинном формате (ниже), но мне нужен в широком формате.

 df <- structure(list(lep = c("ef", "efe", "efef", "efefe", "efefef", 
                             "efefefe", "efefefef", "efefefefe", "efefefefef", "efefefefefef", 
                             "eg"), char_n = c(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 12L, 2L
                             ), char_1 = c("e", "e", "e", "e", "e", "e", "e", "e", "e", "e", 
                                           "e")), row.names = c(NA, -11L), class = c("tbl_df", "tbl", "data.frame"
                                           ))
# A tibble: 11 x 3
   lep          char_n char_1
   <chr>         <int> <chr> 
 1 ef                2 e     
 2 efe               3 e     
 3 efef              4 e     
 4 efefe             5 e     
 5 efefef            6 e     
 6 efefefe           7 e     
 7 efefefef          8 e     
 8 efefefefe         9 e     
 9 efefefefef       10 e     
10 efefefefefef     12 e     
11 eg                2 e   

  

Это результат, который я хотел бы

 # A tibble: 2 x 11
   char_1 x2    x3    x4    x5    x6     x7      x8       x9        x10        x12         
   <chr>  <chr> <chr> <chr> <chr> <chr>  <chr>   <chr>    <chr>     <chr>      <chr>       
 1 e      ef    efe   efef  efefe efefef efefefe efefefef efefefefe efefefefef efefefefefef        
 2 e      eg    NA    NA    NA    NA     NA      NA       NA        NA         NA   
  

Однако, используя следующее, я смог получить только следующий результат:

 df %>%
mutate(row = row_number()) %>%
  pivot_wider(names_from = char_n, values_from=lep) %>% select(-row) %>%
  janitor::clean_names(.)
 
# A tibble: 11 x 11
   char_1 x2    x3    x4    x5    x6     x7      x8       x9        x10        x12         
   <chr>  <chr> <chr> <chr> <chr> <chr>  <chr>   <chr>    <chr>     <chr>      <chr>       
 1 e      ef    NA    NA    NA    NA     NA      NA       NA        NA         NA          
 2 e      NA    efe   NA    NA    NA     NA      NA       NA        NA         NA          
 3 e      NA    NA    efef  NA    NA     NA      NA       NA        NA         NA          
 4 e      NA    NA    NA    efefe NA     NA      NA       NA        NA         NA          
 5 e      NA    NA    NA    NA    efefef NA      NA       NA        NA         NA          
 6 e      NA    NA    NA    NA    NA     efefefe NA       NA        NA         NA          
 7 e      NA    NA    NA    NA    NA     NA      efefefef NA        NA         NA          
 8 e      NA    NA    NA    NA    NA     NA      NA       efefefefe NA         NA          
 9 e      NA    NA    NA    NA    NA     NA      NA       NA        efefefefef NA          
10 e      NA    NA    NA    NA    NA     NA      NA       NA        NA         efefefefefef
11 e      eg    NA    NA    NA    NA     NA      NA       NA        NA         NA    

  

Я не уверен, что изменение способа перехода на более широкий формат или последующие шаги должны отличаться?

Любая помощь будет оценена!

Ответ №1:

Мы создаем ‘rn’ на основе столбца ‘char_n’, а затем используем pivot_wider

 library(dplyr)
library(tidyr)
library(stringr)
df %>%
    mutate(
           rn = cumsum(c(TRUE, diff(char_n) < 0)), char_n = str_c('x', char_n)) %>% 
    pivot_wider(names_from = char_n,  values_from = lep) %>%
    select(-rn)
  

-вывод

 # A tibble: 2 x 11
#  char_1 x2    x3    x4    x5    x6     x7      x8       x9        x10        x12         
#  <chr>  <chr> <chr> <chr> <chr> <chr>  <chr>   <chr>    <chr>     <chr>      <chr>       
#1 e      ef    efe   efef  efefe efefef efefefe efefefef efefefefe efefefefef efefefefefef
#2 e      eg    <NA>  <NA>  <NA>  <NA>   <NA>    <NA>     <NA>      <NA>       <NA>        
  

Ответ №2:

В базовом R вы могли бы использовать reshape :

 reshape(transform(df, id = cumsum(c(0,diff(char_n)<0))), 
         dir='wide', idvar = c('char_1','id'), timevar = 'char_n')

   char_1 id lep.2 lep.3 lep.4 lep.5  lep.6   lep.7    lep.8     lep.9     lep.10       lep.12
1       e  0    ef   efe  efef efefe efefef efefefe efefefef efefefefe efefefefef efefefefefef
11      e  1    eg  <NA>  <NA>  <NA>   <NA>    <NA>     <NA>      <NA>       <NA>         <NA>