R 拆分字符多次出现或不出现的分离(或类似函数)

R 拆分字符多次出现或不出现的分离(或类似函数),r,regex,R,Regex,我有一个像这样的桌子 library("tidyverse") tib <- tibble(x = c("lemon", "yellow, banana", "red, big, apple")) 但这并不是我想要的,屈服: # A tibble: 3 x 3 x description fruit <chr> <chr> <chr> 1 lemon lemon

我有一个像这样的桌子

library("tidyverse")
tib <- tibble(x = c("lemon", "yellow, banana", "red, big, apple"))
但这并不是我想要的,屈服:

# A tibble: 3 x 3
  x               description fruit 
  <chr>           <chr>       <chr> 
1 lemon           lemon       NA    
2 yellow, banana  yellow      banana
3 red, big, apple red         big   
Warning messages:
1: Expected 2 pieces. Additional pieces discarded in 1 rows [3]. 
2: Expected 2 pieces. Missing pieces filled with `NA` in 1 rows [1]. 
有人能给我指出我缺少的部分吗

编辑


不必使用
separate
实现目标<代码>变异也可以,解决方案同样值得赞赏

使用
提取可能更好。在这里,我们可以使用捕获组将角色捕获为一个组。最好从结尾(
$
)开始,然后往回走,即捕获结尾的word(
\\w+
)继承第一个捕获组(
(.*)
)中的
或空格(
\\s
)和所有其他字符

或者使用带有分隔符的regex lookaround,将分隔符指定为
后跟空格或字符串的开头(
^
),然后在字符串的结尾(
$
)指定一个单词(
\\w+

tib %>%
   separate(x, into = c("description", 'fruit'),
       remove = FALSE, '(, |^)(?=\\w+$)') %>%
   mutate(description = na_if(description, ""))

另外,
sep
的另一个选项是在最后一个单词之前插入一个新的分隔符,然后将其用作
sep

library(stringr)
tib %>% 
  mutate(x1 = str_replace(x, ',? ?(\\w+)$', ";\\1")) %>% 
  separate(x1, into = c("description", "fruit"), sep=";") %>%
  mutate(description = na_if(description, ""))
# A tibble: 3 x 3
#  x               description fruit 
#  <chr>           <chr>       <chr> 
#1 lemon           <NA>        lemon 
#2 yellow, banana  yellow      banana
#3 red, big, apple red, big    apple 
库(stringr)
tib%>%
突变(x1=str_替换(x,,??(\\w+$,“;\\1”))%>%
分开(x1,分为=c(“说明”、“水果”),sep=“;”)%>%
变异(描述=na_if(描述“”))
#一个tibble:3x3
#x描述水果
#                     
#1个柠檬
#2黄香蕉黄香蕉
#3红色,大苹果红色,大苹果

您可以使用正则表达式获取描述-替换最后一个逗号及其后面的所有内容
“,[^,]+$”
匹配逗号,后跟任何结尾处不是逗号的内容

要获取水果,请使用
stringr
软件包的
word
功能抓取最后一个单词

tib %>%
    mutate(desc = if_else(grepl(",", x), sub(",[^,]+$", "", x), NA_character_),
           fruit = stringr::word(x, -1))

基于Regex的解决方案,就像这里的另外两个一样,可能更好。但是,如果出于任何原因,您希望使用单词列表,那么这里有另一个选项

将文本拆分为字符串列表。除了位置
长度(单词)
处的项目外,描述内容是所有内容。水果是最后一道菜。如果使用空字符串代替
NA
是可以的,则可以删除
NA\u If

库(dplyr)
tib%
变异(单词=strsplit(x,“,”),
description=purrr::map_chr(words,~paste(.[-length(.)]),collapse=“,”)%%>%na_if(“”),
水果=purrr::map_chr(单词,最后一个))
#>#tibble:3 x 4
#>x词描述水果
#>                          
#>1个柠檬
#>2黄香蕉黄香蕉
#>3红色,大苹果红色,大苹果

显然,您可以删除
单词
列,我留下它只是为了显示它的类型。

它必须使用单独的吗?可能更容易使用变异
tib %>%
   separate(x, into = c("description", 'fruit'),
       remove = FALSE, '(, |^)(?=\\w+$)') %>%
   mutate(description = na_if(description, ""))
library(stringr)
tib %>% 
  mutate(x1 = str_replace(x, ',? ?(\\w+)$', ";\\1")) %>% 
  separate(x1, into = c("description", "fruit"), sep=";") %>%
  mutate(description = na_if(description, ""))
# A tibble: 3 x 3
#  x               description fruit 
#  <chr>           <chr>       <chr> 
#1 lemon           <NA>        lemon 
#2 yellow, banana  yellow      banana
#3 red, big, apple red, big    apple 
tib %>%
    mutate(desc = if_else(grepl(",", x), sub(",[^,]+$", "", x), NA_character_),
           fruit = stringr::word(x, -1))