R - Могу ли я использовать регулярное выражение для разделения данных из одного столбца на несколько новых столбцов и двоичный идентификатор? - PullRequest
0 голосов
/ 15 марта 2020

У меня есть набор данных о символах D & D, который выглядит примерно так

Race   Class              Level   AC
Human  Fighter | Wizard    10     15
Elf    Wizard              8      10
Human  Rogue               6      12
Dwarf  Barbarian           15     18

Я хочу отделить классы, которые являются мультиклассами, обозначенными "|" Также, если персонаж не мультиклассовый, я хочу поместить «NA» или «None» в этот слот

Race   Primary_Class      Level   AC    Subclass   Multiclass
Human  Fighter             10     15    Wizard         1
Elf    Wizard              8      10    NA             0
Human  Rogue               6      12    NA             0
Dwarf  Barbarian           15     18    NA             0

Есть ли чистый способ сделать это?

Ответы [ 3 ]

1 голос
/ 16 марта 2020

Вы можете сделать это с тремя пунктами ifelse, grepl, а также обратными ссылками с \\1 и \\2 соответственно для сопоставления рассматриваемого шаблона и gsub для манипулирования совпадением:

df1$Primary_class <- ifelse(grepl("\\|", df1$Class), 
                            gsub("([A-z]+)\\s\\|\\s([A-z]+)", "\\1", df1$Class), df1$Class)

df1$Subclass <- ifelse(grepl("\\|", df1$Class), 
                            gsub("([A-z]+)\\s\\|\\s([A-z]+)", "\\2", df1$Class), "NA")

df1$Multiclass <- ifelse(grepl("\\|", df1$Class), 1, 0)

df1
   Race            Class Level AC Primary_class Multiclass Sub_class
1 Human Fighter | Wizard    10 15       Fighter          1    Wizard
2   Elf           Wizard     8 10        Wizard          0        NA
3 Human            Rogue     6 12         Rogue          0        NA
4 Dwarf        Barbarian    15 18     Barbarian          0        NA
1 голос
/ 16 марта 2020

Мы можем использовать sub, чтобы удалить все после "|", str_extract, чтобы извлечь все после "|" и использовать str_detect, чтобы определить, присутствует ли "|" в данных.

library(dplyr)
library(stringr)

df %>%
 mutate(Primary_Class = trimws(sub('\\|.*',  '', Class)), 
        Subclass = str_extract(Class, "(?<=\\|).*"), 
        Multiclass = +(str_detect(Class, "\\|"))) %>%
 select(-Class)

#   Race Level AC Primary_Class Subclass Multiclass
#1 Human    10 15      Fighter   Wizard          1
#2   Elf     8 10       Wizard     <NA>          0
#3 Human     6 12        Rogue     <NA>          0
#4 Dwarf    15 18    Barbarian     <NA>          0
0 голосов
/ 15 марта 2020

Мы можем использовать separate, чтобы разделить 'Class' на два столбца ('Primary_Class', 'Subclass'), указав sep как ноль или более пробелов (\\s*), за которыми следуют | и ноль или больше пробелов (\\s*), затем создайте «Мультикласс», проверив, являются ли «Подкласс» NA элементами

library(dplyr)
library(tidyr)
separate(df1, Class, into = c('Primary_Class', 'Subclass'),
      '\\s*\\|\\s*', extra = 'merge') %>%
     mutate(Multiclass = +(!is.na(Subclass)))
#   Race Primary_Class Subclass Level AC Multiclass
#1 Human       Fighter   Wizard    10 15          1
#2   Elf        Wizard     <NA>     8 10          0
#3 Human         Rogue     <NA>     6 12          0
#4 Dwarf     Barbarian     <NA>    15 18          0

data

df1 <- structure(list(Race = c("Human", "Elf", "Human", "Dwarf"), 
   Class = c("Fighter | Wizard", 
"Wizard", "Rogue", "Barbarian"), Level = c(10L, 8L, 6L, 15L), 
    AC = c(15L, 10L, 12L, 18L)), class = "data.frame", row.names = c(NA, 
-4L))
...