Как использовать несколько разделителей в элементе ITEM на основе разных значений в столбце TOOL? - PullRequest
0 голосов
/ 14 февраля 2019

У меня есть такой фрейм данных

ID <- c("A","A","A","A","A","A","A","A","A")
TOOL <- c("ABC_01","ABC_04","ABC_02",
          "DEF_01","DEF_05","DEF_02",
          "IJK_04","IJK_01","IJK_02") 
ITEM <- c("RFALT.2SHEET.S13","RFTACU_789.L_PM.2_N13","CS20_789VIS.200_L_PM.STD",
          "ACRF55_16_T37\\AT_PM3\\1 N1","RFALT\\2SHEET\\S13","RFNF_1_2U\\L_PM3\\5 N13",
          "RFALT 2SHEET S13","CS20_STD 2DUB_L SP C9","RFNC_DBS_T2000 L_EDGE 1 N13") 

df <- data.frame(ID,TOOL,ITEM,stringsAsFactors = F)

Я пытаюсь использовать несколько разделителей на основе столбца TOOL s

  1. Если TOOL LIKE 'ABC', то извлечьстрока в ITEM до . (. является разделителем)
  2. Если TOOL LIKE 'DEF', то извлечь строку в ITEM до \ (\ является разделителем)
  3. Если TOOL LIKE 'IJK', то извлечь строку в ITEM до (пробел - разделитель)

Желаемый вывод

  ID   TOOL           ITEM
   A ABC_01          RFALT
   A ABC_04     RFTACU_789
   A ABC_02    CS20_789VIS
   A DEF_01  ACRF55_16_T37
   A DEF_05          RFALT
   A DEF_02      RFNF_1_2U
   A IJK_04          RFALT
   A IJK_01       CS20_STD
   A IJK_02 RFNC_DBS_T2000

Я пытаюсь сделать это таким образом, используя dplyr & stringr пакеты

library(dplyr)
library(stringr)
df2 <- df %>%
  filter(grepl("ABC",TOOL)) %>% 
  mutate(ITEM = str_extract(ITEM, "^.*(?=.\\)")) %>% 
  filter(grepl("DEF",TOOL)) %>% 
  mutate(ITEM = str_extract(ITEM, "^.*(?=.\.)"))

Это не работает.Может ли кто-нибудь указать мне правильное направление?

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Один вариант с str_remove

library(tidyverse)
df %>%
     mutate(ITEM = str_remove(ITEM, "[.\\\\ ].*"))
#  ID   TOOL           ITEM
#1  A ABC_01          RFALT
#2  A ABC_04     RFTACU_789
#3  A ABC_02    CS20_789VIS
#4  A DEF_01  ACRF55_16_T37
#5  A DEF_05          RFALT
#6  A DEF_02      RFNF_1_2U
#7  A IJK_04          RFALT
#8  A IJK_01       CS20_STD
#9  A IJK_02 RFNC_DBS_T2000

Если шаблон специфичен для определенного «ИНСТРУМЕНТА», один вариант будет применяться str_remove отдельно

map2_df(c("ABC", "DEF", "IJK"), c(".", "\\\\", " "), ~ 
      df %>% 
         filter(str_detect(TOOL, .x)) %>%
         mutate(ITEM = str_remove(ITEM, paste0("[", .y, "].*"))))
#  ID   TOOL           ITEM
#1  A ABC_01          RFALT
#2  A ABC_04     RFTACU_789
#3  A ABC_02    CS20_789VIS
#4  A DEF_01  ACRF55_16_T37
#5  A DEF_05          RFALT
#6  A DEF_02      RFNF_1_2U
#7  A IJK_04          RFALT
#8  A IJK_01       CS20_STD
#9  A IJK_02 RFNC_DBS_T2000
0 голосов
/ 14 февраля 2019

Мы можем использовать case_when и str_replace.

library(tidyverse)

df2 <- df %>%
  mutate(ITEM = case_when(
    str_detect(TOOL, "^ABC")     ~str_replace(ITEM, "[\\.].*", ""),
    str_detect(TOOL, "^DEF")     ~str_replace(ITEM, "[\\\\].*", ""),
    str_detect(TOOL, "^IJK")      ~str_replace(ITEM, "[:space:].*", "")
  ))
df2
#   ID   TOOL           ITEM
# 1  A ABC_01          RFALT
# 2  A ABC_04     RFTACU_789
# 3  A ABC_02    CS20_789VIS
# 4  A DEF_01  ACRF55_16_T37
# 5  A DEF_05          RFALT
# 6  A DEF_02      RFNF_1_2U
# 7  A IJK_04          RFALT
# 8  A IJK_01       CS20_STD
# 9  A IJK_02 RFNC_DBS_T2000
0 голосов
/ 14 февраля 2019

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

library(dplyr)
df %>% 
  mutate(ITEM2 = ITEM %>% strsplit('\\.| |\\\\') %>% sapply(`[[`, 1))

#   ID   TOOL                        ITEM          ITEM2
# 1  A ABC_01            RFALT.2SHEET.S13          RFALT
# 2  A ABC_04       RFTACU_789.L_PM.2_N13     RFTACU_789
# 3  A ABC_02    CS20_789VIS.200_L_PM.STD    CS20_789VIS
# 4  A DEF_01 ACRF55_16_T37\\AT_PM3\\1 N1  ACRF55_16_T37
# 5  A DEF_05          RFALT\\2SHEET\\S13          RFALT
# 6  A DEF_02     RFNF_1_2U\\L_PM3\\5 N13      RFNF_1_2U
# 7  A IJK_04            RFALT 2SHEET S13          RFALT
# 8  A IJK_01       CS20_STD 2DUB_L SP C9       CS20_STD
# 9  A IJK_02 RFNC_DBS_T2000 L_EDGE 1 N13 RFNC_DBS_T2000
...