I wrote this function to return the string before a certain character, which goes like so:
strBefore <- function(find, x, last = FALSE, occurence) {
# Checking.
if (class(x)[1] != "character") { stop("The strBefore function only supports objects of character class.") }
# Getting the place of the find, and handling both caes of last.
fullPlace <- gregexpr(find, x)[[1]] # Gets the location of the occurences of find in x.
# Handling the case where last is TRUE.
if (last == TRUE) { place <- max(fullPlace) # Grabbing the latest character index if last is TRUE.
} else { place <- min(fullPlace) } # Otherwise, getting the first space.
# Handles the occurrenceargument if given.
if (!missing(occurrence)) { place <- fullPlace[occurrence] }
# Subsetting the string.
xlen <- nchar(x) # Getting the total number of characters in the string.
x <- substr(x, 1, place - 1) # Minus 1 because we don't want to include the first hit for find.
return(x)
}
Where find
is the character you want the string before, x
is the character, last
asks if you to get before the last occurrence of find
, and occurrence
designates which occurrence of find
to get before (overrides last
if given).
If I use it on a single character object, it works fine like so:
> test <- "Hello World"
> test2 <- strBefore(" ", test)
> test2
[1] "Hello"
However, if I use it on a character vector, it cuts each item in the vector at the same place as the first item:
> test <- c("Hello World", "Hi There", "Why Hello")
> test2 <- strBefore(" ", test)
> test2
[1] "Hello" "Hi Th" "Why H"
Now, this link here does provide me with a method for doing what I want:
Using gsub to extract character string before white space in R
However, I do like having the functionality of the "occurrence" argument, which returns the string before the 2nd, 3rd, etc... occurrence of the find argument.
Just as a note, I can vectorize my function with sapply
like so:
> test <- c("Hello World", "Hi There", "Why Hello")
> test2 <- sapply(test, function(x) strBefore(" ", x))
> test2
Hello World Hi There Why Hello
"Hello" "Hi" "Why"
Which somewhat solves my problem...but is there a way to do this more cleanly without having to use an apply
function? I'm not looking for a solution to what strBefore
does, but more a solution to how to vectorize custom functions. Thanks for your time.