Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tidyr separate only first n instances [duplicate]

Tags:

r

tidyr

I have a data.frame in R, which, for simplicity, has one column that I want to separate. It looks like this:

V1
Value_is_the_best_one
This_is_the_prettiest_thing_I've_ever_seen
Here_is_the_next_example_of_what_I_want

My real data is very large (millions of rows), so I'd like to use tidyr's separate function (because it's amazingly fast) to separate out JUST the first few instances. I'd like the result to be the following:

V1       V2     V3     V4 
Value    is     the    best_one
This     is     the    prettiest_thing_I've_ever_seen
Here     is     the    next_example_of_what_I_want

As you can see, the separator is _ the V4 column can have different numbers of the separators. I want to keep V4 (not discard it), but not have to worry about how much stuff is in there. There will always be four columns (i.e. none of my rows have only V1-V3).

Here is my starting tidyr command I've been working with:

separate(df, V1, c("V1", "V2", "V3", "V4"), sep="_")

This gets rid of V4 (and spits out warnings, which isn't the biggest deal).

like image 570
Gaius Augustus Avatar asked May 09 '16 22:05

Gaius Augustus


2 Answers

You need the extra argument with the "merge" option. This allows only as many splits as you have new columns defined.

separate(df, V1, c("V1", "V2", "V3", "V4"), extra = "merge")

     V1 V2  V3                             V4
1 Value is the                       best_one
2  This is the prettiest_thing_I've_ever_seen
3  Here is the    next_example_of_what_I_want
like image 53
aosmith Avatar answered Nov 06 '22 17:11

aosmith


Here is another option with extract

library(tidyr)
extract(df1, V1, into = paste0("V", 1:4), "([^_]+)_([^_]+)_([^_]+)_(.*)")
#      V1 V2  V3                             V4
# 1 Value is the                       best_one
# 2  This is the prettiest_thing_I've_ever_seen
# 3  Here is the    next_example_of_what_I_want

Another option is stri_split from library(stringi) where we can specify the number of splits

library(stringi)
do.call(rbind, stri_split(df1$V1, fixed="_", n=4))
like image 6
akrun Avatar answered Nov 06 '22 17:11

akrun