Условно разделяющие переменные dplyr - PullRequest
0 голосов
/ 15 января 2019

Рассмотрим минимальный рабочий пример очень грязного набора данных, с которым я работаю:

library(dplyr)
library(tidyr)

x<- paste(sort(rep(LETTERS[1:4], 3)), paste0(rep("#", 3), rep(11:13, 3)))
y<- paste(sort(rep(LETTERS[1:4], 2)), paste0(rep(1:2, 2), rep("/0", 2)))
data<- data.frame(Item = c(x, y))

, что дает:

    Item
1  A #11
2  A #12
3  A #13
4  B #11
5  B #12
6  B #13
7  C #11
8  C #12
9  C #13
10 D #11
11 D #12
12 D #13
13 A 1/0
14 A 2/0
15 B 1/0
16 B 2/0
17 C 1/0
18 C 2/0
19 D 1/0
20 D 2/0

Я хочу разделить пункт на элемент и размер. Есть два типа размеров. Первое, 11:13, которое обозначено #. Второй, 1/0: 2/0, который может быть идентифицирован как /0 в этом примере. Для отделения первого типа размера от Item data %>% separate(Item, into = c("Item", "Size"), sep = "#") используется. Это, однако, выводит NA в строках 13:20.

Как можно отделить переменную в соответствии с условием, чтобы разделить элемент и размер второго типа размера?

Я попробовал приведенный ниже код, но безуспешно.

data %>% 
        separate(Item, into = c("Item", "Size"), sep = "#") %>% 
        mutate(ifelse(grepl("/0", Item) == TRUE, separate(Item, into = c("Item", "Size"), sep = " (?=[^ ]+$)", perl=TRUE), Size))

EDIT

Желаемый результат должен выглядеть следующим образом:

   Item Size
1     A   11
2     A   12
3     A   13
4     B   11
5     B   12
6     B   13
7     C   11
8     C   12
9     C   13
10    D   11
11    D   12
12    D   13
13    A  1/0
14    A  2/0
15    B  1/0
16    B  2/0
17    C  1/0
18    C  2/0
19    D  1/0
20    D  2/0

Ответы [ 3 ]

0 голосов
/ 15 января 2019

Чтобы ответить на ваш вопрос | Оператор позволяет выбрать несколько разделителей.

data %>% 
  separate(Item, into = c("Item", "Size"), sep = " #| ")

Или вы можете использовать общий символ "", чтобы разделить все, а затем очистить столбец после:

data %>% 
      separate(Item, into = c("Item", "Size"), sep = " ")

См. https://stringr.tidyverse.org/articles/regular-expressions.html для получения дополнительной информации о регулярных выражениях, которая поможет вам в уборке. Если это неопрятный текст, который вы полюбите и вам понадобится stringR

0 голосов
/ 16 января 2019

Так как Size имеет шаблон <<code># и цифру> или цифру после пробела, он переходит к аргументу sep.

  1. " #(?=[0-9])" находит шаблон, например " #1"
  2. " [0-9]" находит шаблон, например, " 1"
  3. | означает или

В сумме, (Предполагая, что эти типы шаблонов не встречаются в имени элемента )

library(tidyverse)
x <- paste(sort(rep(LETTERS[1:4], 3)), paste0(rep("#", 3), rep(11:13, 3)))
y <- paste(sort(rep(LETTERS[1:4], 2)), paste0(rep(1:2, 2), rep("/0", 2)))
mydf <- data_frame(Item = c(x, y))
#---------------------------------
mydf %>% 
  separate(Item, into = c("Item", "Size"), sep = " #(?=[0-9])| (?=[0-9])")
#> # A tibble: 20 x 2
#>    Item  Size 
#>    <chr> <chr>
#>  1 A     11   
#>  2 A     12   
#>  3 A     13   
#>  4 B     11   
#>  5 B     12   
#>  6 B     13   
#>  7 C     11   
#>  8 C     12   
#>  9 C     13   
#> 10 D     11   
#> 11 D     12   
#> 12 D     13   
#> 13 A     1/0  
#> 14 A     2/0  
#> 15 B     1/0  
#> 16 B     2/0  
#> 17 C     1/0  
#> 18 C     2/0  
#> 19 D     1/0  
#> 20 D     2/0
0 голосов
/ 15 января 2019

Я думаю, это может быть то, что вы ищете. Разделите пробел, а затем замените либо #, либо / 0 на пустое, если я не понял неправильно.

data %>%
  separate(Item, into = c("Item", "Size"), sep = " ") %>%
  mutate(Size = gsub("/0|#", "", Size))
...