Markm0705
Markm0705

Reputation: 1440

How do I split a string at character and subset the left or right side?

Say I have a file of characters that I would like to split at a character and then select the left side of the split to a new field. Is there a way to do this one step? For example:

x <- strsplit('dark_room',"_")
x[[1]][2]
[1] "room"

Is a two-step operation to access the "room" - how can I subset "room" in one operation?

Upvotes: 1

Views: 1740

Answers (3)

Shree
Shree

Reputation: 11150

Here's a way using sub from base R which just removes everything up to the first underscore -

# for left side of '_'
sub(".*_", "", x)    
[1] "room"

# for right side of '_'
sub("(.*)_.*", "\\1", x)
[1] "dark"

Upvotes: 3

d.b
d.b

Reputation: 32558

Define your own functions (using the solution in your question or any of the other solutions from the answers)

left = function(x, sep){
    substring(x, 1, regexpr(sep, x) - 1)
}
right = function(x, sep){
    substring(x, regexpr(sep, x) + 1, nchar(x))
}

s = c("dark_room")

left(s, "_")
#[1] "dark"

right(s, "_")
#[1] "room"

Upvotes: 2

akrun
akrun

Reputation: 887711

An easier option is to use word from stringr and specify the sep and other parameters

library(stringr)
word('dark_room', -1, sep="_")
#[1] "room"

Or with str_extract to match characters other than _ ([^_]+) at the end ($) of the string

str_extract('dark_room', "[^_]+$")
#[1] "room"

Or with stri_extract from stringi where we can specify the first and last

library(stringi)
stri_extract_first('dark_room', regex = '[^_]+')
#[1] "dark"
stri_extract_last('dark_room', regex = '[^_]+')
#[1] "room"

The strsplit always returns a list. So, as a general case (applicable when there are more than one element) would be to loop through the list with sapply and subset with either tail

sapply( strsplit('dark_room',"_"), tail, 1)
#[1] "room"

or head to get the first n elements

Or using scan

tail(scan(text = 'dark_room', what = "", sep="_"), 1)

Upvotes: 3

Related Questions