Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R split string at last whitespace chars using tidyr::separate

Tags:

regex

r

dplyr

tidyr

Suppose I have a dataframe like this:

df<-data.frame(a=c("AA","BB"),b=c("short string","this is the longer string"))

I would like to split each string using a regex based on the last space occuring. I tried:

library(dplyr)
library(tidyr)
df%>%
  separate(b,c("partA","partB"),sep=" [^ ]*$")

But this omits the second part of the string in the output. My desired output would look like this:

   a              partA  partB
1 AA              short string
2 BB this is the longer string

How do I do this. Would be nice if I could use tidyr and dplyr for this.

like image 285
user2386786 Avatar asked Aug 20 '15 13:08

user2386786


2 Answers

You may turn the [^ ]*$ part of your regex into a (?=[^ ]*$) non-consuming pattern, a positive lookahead (that will not consume the non-whitespace chars at the end of the string, i.e. they won't be put into the match value and thus will stay there in the output):

df%>%
  separate(b,c("partA","partB"),sep=" (?=[^ ]*$)")

Or, a bit more universal since it matches any whitespace chars:

df %>%
  separate(b,c("partA","partB"),sep="\\s+(?=\\S*$)")

See the regex demo and its graph below:

enter image description here

Output:

   a              partA  partB
1 AA              short string
2 BB this is the longer string
like image 145
Wiktor Stribiżew Avatar answered Oct 22 '22 19:10

Wiktor Stribiżew


We can use extract from tidyr by using the capture groups ((...)). We match zero or more characters (.*) and place it within the parentheses ((.*)), followed by zero or more space (\\s+), followed by the next capture group which includes only characters that are not a space ([^ ]) until the end ($) of the string.

library(tidyr)
extract(df, b, into = c('partA', 'partB'), '(.*)\\s+([^ ]+)$')
#   a              partA  partB
#1 AA              short string
#2 BB this is the longer string
like image 29
akrun Avatar answered Oct 22 '22 19:10

akrun