Home > Blockchain >  How to extract specific words from a string with pattern in R
How to extract specific words from a string with pattern in R

Time:06-05

I have a dataframe which contains the names of supervisors and advisors of students' dissertations in a faculty as follows for example:

 DF<-data.frame(Names=c("Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
  "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
  "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3"))

I gonna separate supervisors and advisors as two distinct columns (as my expectation) like this:

DF1<-data.frame(Supervisor=c("Ali Ahmadi","Ali Ahmadi","Ali Ahmadi"),Advisors=c("Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi","Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi","Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi"))

DF1
  Supervisor                                             Advisors
1 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi
2 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi
3 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi

I tried following codes:

DF1<-strsplit(DF$Names, "Name :")

stopwords = c(":","Type","Family","Name","1","2", "3", "Advisor", "Family")

DF2 <- lapply(DF1,function(x) unlist(strsplit(x," ")) )

DF3 <- lapply(DF2,function(x)  x[!x %in% stopwords] )

DF4<-lapply(DF3,function(x)  paste(x, collapse = " "))

But the final results as follows is not what was my expectation and apparently need further work to be converted to a datataframe!:

DF4
[[1]]
[1] " Ali , Ahmadi , First supervisor  Aram , Rezaeei ,  Omid , Saeedi ,  Nima , Shaki ,  Sohrab , Karimi ,"

[[2]]
[1] " Ali , Ahmadi , First supervisor  Aram , Rezaeei ,  Omid , Saeedi ,  Nima , Shaki ,  Sohrab , Karimi ,"

[[3]]
[1] " Ali , Ahmadi , First supervisor  Aram , Rezaeei ,  Omid , Saeedi ,  Nima , Shaki ,  Sohrab , Karimi ,"

Is there any simplified method to solve the problem? I found regexp can be helpful but I don't know how to use it atleast in the case of my example. Thanks in advance for any answer...

CodePudding user response:

Here's an attempt with extract:

library(tidyr)
DF %>%
  # clean strings:
  mutate(Names = gsub("\\s?(Name|Family|First supervisor|Advisor|Type|\\d|\\s[,:])", "", Names, perl = TRUE)) %>%
  # extract data into columns:
  extract(Names,
          into = c("Supervisor", "Advisor"),
          regex = "(\\w \\s\\w )\\s(.*)") %>%
  # insert commas into `Advisor`:
  mutate(Advisor = gsub("(\\w \\s\\w \\b)(?!$)", "\\1,", Advisor, perl = TRUE))
  Supervisor                                              Advisor
1 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi
2 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi
3 Ali Ahmadi Aram Rezaeei, Omid Saeedi, Nima Shaki, Sohrab Karimi

Data:

DF<-data.frame(Names=c("Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
                       "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
                       "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3"))

CodePudding user response:

Here is a base R solution.

DF <- data.frame(Names=c("Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
                       "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3",
                       "Name : Ali , Family : Ahmadi , Type : First supervisor Name : Aram , Family : Rezaeei , Type : Advisor Name : Omid , Family : Saeedi , Type : Advisor 1 Name : Nima , Family : Shaki , Type : Advisor 2 Name : Sohrab , Family : Karimi , Type : Advisor 3"))

stopwords <- c(":","Type","Family","Name","1","2", "3", "Advisor", "Family")
stoppattern <- paste(stopwords, collapse = "|")

DF1 <- strsplit(DF$Names, "Name :")
DF1 <- lapply(DF1, \(x) trimws(x[sapply(x, nchar) > 0L]))

DF2 <- lapply(DF1, \(x) {
  gsub(stoppattern, "", x)
})

DF3 <- lapply(DF2, \(x) {
  y <- gsub(stoppattern, "", x)
  y <- strsplit(x, ",")
  y <- lapply(y, trimws)
  lapply(y, \(.y) {
    .y <- trimws(.y)
    .y[sapply(.y, nchar) > 0L]
  })
})

DF4 <- lapply(DF3, \(x) {
  Supervisor <- x[[1]][1:2]
  Supervisor <- paste(trimws(Supervisor), collapse = " ")
  Advisors <- unlist(x[-1])
  Advisors <- paste(trimws(Advisors), collapse = ", ")
  data.frame(Supervisor, Advisors)
})

Final <- do.call(rbind, DF4)
Final
#>   Supervisor                                                 Advisors
#> 1 Ali Ahmadi Aram, Rezaeei, Omid, Saeedi, Nima, Shaki, Sohrab, Karimi
#> 2 Ali Ahmadi Aram, Rezaeei, Omid, Saeedi, Nima, Shaki, Sohrab, Karimi
#> 3 Ali Ahmadi Aram, Rezaeei, Omid, Saeedi, Nima, Shaki, Sohrab, Karimi

Created on 2022-06-05 by the reprex package (v2.0.1)

  • Related