/ / cSplit Coerces Niepotrzebny NA Row - r, string, delimiter, splitstackshape, csplit

cSplit Coerces Niepotrzebny NA Row - r, string, delimiter, splitstackshape, csplit

Mam duży zestaw danych, którego mała próbka wygląda jak 4-krotna wartość dodana poniżej. Próbuję podzielić wiele rozgraniczonych kolumn na unikalne wiersze za pomocą zmiennej c=="Split" jak poniżej:

library(splitstackshape)

dt <- tibble(
a = c("Quartz | White Spirit | Wildfire", "Quiet Riot", "Race Against Time", "Down | Heart Lane | X | Breaking H"),
b = c("Muthas Pride", "Killer Girls / Slick Black Cadillac", "Demo 1980", "Life 55"),
c = c("Split", "Single", "Demo", "Split"),
d = c("Birmingham, England | Hartlepool, England | Sheffield, South Yorkshire, England", "Los Angeles, California", "Nottingham, England", "Liverpool | Beijing | | NYC"),
e = c("wf | ef | ff", "g", "f", "cf | af | df | rf")
)

dt.s <- subset(dt, c == "Split")
dt.split <- cSplit(dt.s, c("a", "d", "e"), c("|", "|", "|"), "long")
dt.split

Wymusza to jednak dodatkowy rząd NA, jak widać w rzędzie 4:

             a            b     c                                   d  e
1:       Quartz Muthas Pride Split                 Birmingham, England wf
2: White Spirit Muthas Pride Split                 Hartlepool, England ef
3:     Wildfire Muthas Pride Split Sheffield, South Yorkshire, England ff
4:           NA Muthas Pride Split                                  NA NA
5:         Down      Life 55 Split                           Liverpool cf
6:   Heart Lane      Life 55 Split                             Beijing af
7:            X      Life 55 Split                                     df
8:   Breaking H      Life 55 Split                                 NYC rf

Nie stanowi to problemu, jeśli podzielę tylko dwie kolumny. Jak sprawić, by nie generował wiersza NA? I czy jest jakiś sposób na zrobienie cSplit praca bez podzbioru wg c?

Odpowiedzi:

0 dla odpowiedzi № 1

Ponieważ używamy a tibble, możemy użyć separate_rows, która nie daje NA wydziwianie

library(tidyr)
separate_rows(dt.s, c("a", "d", "e"), sep="\s*\|\s*") %>%
select_at(names(dt.s))
# A tibble: 7 x 5
#             a            b     c                                   d     e
#         <chr>        <chr> <chr>                               <chr> <chr>
#1       Quartz Muthas Pride Split                 Birmingham, England    wf
#2 White Spirit Muthas Pride Split                 Hartlepool, England    ef
#3     Wildfire Muthas Pride Split Sheffield, South Yorkshire, England    ff
#4         Down      Life 55 Split                           Liverpool    cf
#5   Heart Lane      Life 55 Split                             Beijing    af
#6            X      Life 55 Split                                        df
#7   Breaking H      Life 55 Split                                 NYC    rf

Odnośnie, dlaczego cSplit daje dodatkowy rząd NA, lepiej byłoby sprawdzić wyjście w "szerokim" formacie

cSplit(dt.s, c("a", "d", "e"), "|")
#              b     c    a_1          a_2      a_3        a_4                 d_1                 d_2                                 d_3 d_4 e_1 e_2 e_3 e_4
#1: Muthas Pride Split Quartz White Spirit Wildfire         NA Birmingham, England Hartlepool, England Sheffield, South Yorkshire, England  NA  wf  ef  ff  NA
#2:      Life 55 Split   Down   Heart Lane        X Breaking H           Liverpool             Beijing                                     NYC  cf  af  df  rf

Tutaj stwierdzamy, że dla drugiego rzędu liczba ograniczników, tj. | to 4 tworzenie NA dla pierwszego wiersza, ponieważ istnieją tylko 3 ograniczniki dla kolumny "a. Gdy używamy formatu" długiego ", NA rząd propaguje. To może być błąd.


0 dla odpowiedzi nr 2

Spróbuj dodać makeEqual = FALSE dla Twojej cSplit połączenie:

cSplit(dt.s, c("a", "d", "e"), "|", "long", makeEqual = FALSE)
##               a            b     c                                   d  e
## 1:       Quartz Muthas Pride Split                 Birmingham, England wf
## 2: White Spirit Muthas Pride Split                 Hartlepool, England ef
## 3:     Wildfire Muthas Pride Split Sheffield, South Yorkshire, England ff
## 4:         Down      Life 55 Split                           Liverpool cf
## 5:   Heart Lane      Life 55 Split                             Beijing af
## 6:            X      Life 55 Split                                     df
## 7:   Breaking H      Life 55 Split                                 NYC rf

Ponadto, ponieważ już używasz pakietów z "tidyverse", możesz podzbiorować razem z dzieleniem, tak jak poniżej:

dt %>%
filter(c == "Split") %>%
cSplit(c("a", "d", "e"), "|", "long", makeEqual = FALSE)