mike805 mike805 - 11 days ago 7
R Question

Extract words from string in R

I am trying to extract pieces of the string and creating new variables from those matched patterns. I have tried numerous of functions from the "strings" package and can't seem to get the outcome. The example below is made up data. I want to take a character string and extract the pieces and store them into new columns of a new data frame.

example



ex <- c("The Accountant (2016)Crime (vodmovies112.blogspot.com.es)","Miss Peregrine's Home for Peculiar Children (2016)FantasySci-Fi (vodmovies112.blogspot.com.es),"Fantastic Beasts And Where To Find Them (2016) TSAdventure (openload.co)","Ben-Hur (2016) HDActionAdventure (vodmovies112.blogspot.com.es)","The Remains (2016) 1080p BlurayHorror (openload.co)" ,"Suicide Squad (2016) HDAction (openload.co)")

>ex
[1] "The Accountant (2016)Crime (vodmovies112.blogspot.com.es)"
[2] "Miss Peregrine's Home for Peculiar Children (2016)FantasySci-Fi (vodmovies112.blogspot.com.es)"
[3] "Fantastic Beasts And Where To Find Them (2016) TSAdventure (openload.co)"
[4] "Ben-Hur (2016) HDActionAdventure (vodmovies112.blogspot.com.es)"
[5] "The Remains (2016) 1080p BlurayHorror (openload.co)"
[6] "Suicide Squad (2016) HDAction (openload.co)"

genres <- c("Action","Adventure","Animation","Biography",
"Comedy","Crime","Documentary","Drama","Family",
"Fantasy","Film-Noir","History","Horror","Music",
"Musical","Mystery","Romance","Sci-Fi","Sport","Thriller",
"War","Western")

genres <- paste0("^",genres,"|")
genres[22] <- "^Western"
> genres
[1] "^Action|" "^Adventure|" "^Animation|" "^Biography|"
[5] "^Comedy|" "^Crime|" "^Documentary|" "^Drama|"
[9] "^Family|" "^Fantasy|" "^Film-Noir|" "^History|"
[13] "^Horror|" "^Music|" "^Musical|" "^Mystery|"
[17] "^Romance|" "^Sci-Fi|" "^Sport|" "^Thriller|"
[21] "^War|" "^Western"


trying to accomplish



> df
title year domain genre
1 The Accountant 2016 vodmovies112.blogspot.com.es Crime

Answer

Here is a possibility:

temp <- strsplit(ex, "\\(|\\)")
df <- setNames(as.data.frame(lapply(1:4,function(i) sapply(temp,"[",i)), stringsAsFactors = FALSE), c("title", "year", "genre", "domain"))
df <- df[ , c("title", "year", "domain", "genre")]
correct <- sapply(seq_along(df$genre), function(y) which(lengths(sapply(seq_along(genres), function(x) grep(genres[x], df$genre[y])))>0))
correct <- lapply(correct, function(x) paste0(genres[x], collapse = " "))
df$genre <- unlist(correct)

df
#                                         title year                       domain            genre
# 1                              The Accountant  2016 vodmovies112.blogspot.com.es            Crime
# 2 Miss Peregrine's Home for Peculiar Children  2016 vodmovies112.blogspot.com.es   Fantasy Sci-Fi
# 3     Fantastic Beasts And Where To Find Them  2016                  openload.co        Adventure
# 4                                     Ben-Hur  2016 vodmovies112.blogspot.com.es Action Adventure
# 5                                 The Remains  2016                  openload.co           Horror
# 6                               Suicide Squad  2016                  openload.co           Action

Basically, we split the vector ex in 4 parts, delimited by the parenthesis. We then create the data.frame df with the 4 columns. The hardest part is to correctly extract the genre (as there might be more than one genre per movie). I use a combination of sapply, lapply and grep to do it. When that's done, we "correct" the column genre.

Here is your data:

ex <- c("The Accountant (2016)Crime (vodmovies112.blogspot.com.es)", 
"Miss Peregrine's Home for Peculiar Children (2016)FantasySci-Fi (vodmovies112.blogspot.com.es)", 
"Fantastic Beasts And Where To Find Them (2016) TSAdventure (openload.co)", 
"Ben-Hur (2016) HDActionAdventure (vodmovies112.blogspot.com.es)", 
"The Remains (2016) 1080p BlurayHorror (openload.co)", "Suicide Squad (2016) HDAction (openload.co)"
)

genres <- c("Action", "Adventure", "Animation", "Biography", "Comedy", 
"Crime", "Documentary", "Drama", "Family", "Fantasy", "Film-Noir", 
"History", "Horror", "Music", "Musical", "Mystery", "Romance", 
"Sci-Fi", "Sport", "Thriller", "War", "Western")