Разделить столбец по нескольким разделителям и порядку

#r #strsplit

#r #strsplit

Вопрос:

Я пытаюсь проанализировать некоторые составы daily fantasy, и мне нужно разделить столбец lineup на несколько столбцов, по одному для каждой позиции.

Я бы хотел, чтобы разделителями были позиции («P», «C», «1B», «2B», «SS», «3B», «OF»).

Я пытался использовать str_split и separate, но немного запутался в том, как бы я собрал их в отдельные столбцы, а затем упорядочил.

Вот столбец, который я хочу разделить:

 Lineup
1B Justin Bour P José Berríos P Justin Verlander 2B Kiké Hernández OF Cody Bellinger OF Joc Pederson C Austin Barnes SS Corey Seager OF Corey Dickerson 3B Jung Ho Kang
P José Berríos OF Albert Almora Jr. SS Javier Báez 3B Kris Bryant 2B Ben Zobrist 1B Anthony Rizzo OF Cody Bellinger OF Joc Pederson C Austin Barnes P Eric Lauer
  

Я бы хотел, чтобы это выглядело как:

 P             | P                 | C               | 1B              | 2B .. and so on...
------------- | ----------------- | --------------- | --------------- |
José Berríos  | Justin Verlander  | Austin Barnes   | Justin Bour     |
José Berríos  | Eric Lauer        | Austin Barnes   | Anthony Rizzo   |
  

Комментарии:

1. Каков источник этих данных? Не так уж сложно использовать какое-нибудь регулярное выражение, чтобы помочь преобразовать его в удобный формат, но выглядит так, как будто оно, возможно, было извлечено откуда-то, где оно уже было структурировано. Если это так, было бы лучше взять его оттуда и сохранить структуру нетронутой.

Ответ №1:

Вот вариант

 pos <- c("P", "C", "1B", "2B", "3S", "3B", "OF", "SS")
pat <- sprintf("(%s)", paste(pos, collapse = "|"))

library(tidyverse)
unlist(str_split(Lineup, "n")) %>%
    str_split(sprintf("((?<=(%s\b))\s|\s(?=(%s\b)))", pat, pat)) %>%
    map(~as_tibble(matrix(.x, ncol = 2, byrow = T)) %>%
        group_by(V1) %>%
        mutate(n = 1:n()) %>%
        unite(col, V1, n, sep = "_") %>%
        spread(col, V2)) %>%
    bind_rows()
## A tibble: 2 x 10
#  `1B_1`   `2B_1`   `3B_1`   C_1     OF_1    OF_2   OF_3   P_1    P_2     SS_1
#  <chr>    <chr>    <chr>    <chr>   <chr>   <chr>  <chr>  <chr>  <chr>   <chr>
#1 Justin … Kiké He… Jung Ho… Austin… Cody B… Joc P… Corey… José … Justin… Corey…
#2 Anthony… Ben Zob… Kris Br… Austin… Albert… Cody … Joc P… José … Eric L… Javie…
  

Объяснение: Сначала мы определяем все позиции (обратите внимание, что вы забыли "SS" указать разделитель для возможных позиций) и преобразуем их в регулярное выражение OR в pat . Затем мы можем разделить входную строку Lineup сначала на "n" (для разных строк), а затем на pat . Остальное — это довольно простая tidyverse перестройка. Обратите внимание, что, поскольку одни и те же позиции могут встречаться несколько раз, а позиции должны быть названиями столбцов в соответствии с вашим дизайном, нам нужно «унифицировать-ify» позиции, добавив число.


Пример данных

 Lineup <-
"1B Justin Bour P José Berríos P Justin Verlander 2B Kiké Hernández OF Cody Bellinger OF Joc Pederson C Austin Barnes SS Corey Seager OF Corey Dickerson 3B Jung Ho Kang
P José Berríos OF Albert Almora Jr. SS Javier Báez 3B Kris Bryant 2B Ben Zobrist 1B Anthony Rizzo OF Cody Bellinger OF Joc Pederson C Austin Barnes P Eric Lauer"