Get everything to the left of ? in a string during dplyr chain with mutate

Viewed 92
df <- data.frame(
  strings = c('blah?ha', 'foo?bar', 'cats?dogs')
)

df %>% 
  mutate(first_word = str_split(strings, fixed('?')))

     strings first_word
 strings first_word
1   blah?ha   blah, ha
2   foo?bar   foo, bar
3 cats?dogs cats, dogs

This gets me close to my goal. I just want the first part though, blah, foo and cats. Tried:

 df %>% 
+   mutate(first_word = str_split(strings, fixed('?'))[[1]][[1]])
    strings first_word
1   blah?ha       blah
2   foo?bar       blah
3 cats?dogs       blah

This gives me the same word repeated down the column.

How can I get a new column with the values blah, foo and cats?

1 Answers

We can use str_extract to match one or more characters that are not a ? ([^?]+) from the start (^) Of the string

library(dplyr)
library(stringr)
df %>%
   mutate(first_word = str_extract(strings, "^[^?]+"))

Or use trimws with whitespace as a regex

df %>%
    mutate(first_word = trimws(strings, whitespace = "\\?.*"))

Or similar code in base R

df$first_word <- with(df, trimws(strings, whitespace = "\\?.*"))

The issue in OP's code is that it is extracting only the first list element ([[1]]) from the str_split. It needs to loop over the list and get the first element

library(purrr)
df %>%
    mutate(first_word = map_chr(str_split(strings, fixed("?")), first))
#    strings first_word
#1   blah?ha       blah
#2   foo?bar        foo
#3 cats?dogs       cats    
Related