Как обнаружить подстроки из нескольких списков внутри строки в R


Я пытаюсь найти, содержит ли строка под названием "values" подстроки из двух разных списков. Вот мой текущий код:

for (i in 1:length(value)){
  for (j in 1:length(city)){
    if (str_detect(value[i],(city[j]))) == TRUE){
        for (k in 1:length(school)){
            if (str_detect(value[i],(school[j]))) == TRUE){
        ...........................................................
        }
      }
    }
  }
}

city и school - это отдельные векторы разной длины, каждый из которых содержит элементы строки.

city <- ("Madrid", "London", "Paris", "Sofia", "Cairo", "Detroit", "New York")
school <- ("Law", "Mathematics", "PoliSci", "Economics")
value <- ("Rey Juan Carlos Law Dept, Madrid", "New York University, Center of PoliSci Studies", ..........)
Что я хочу сделать, так это посмотреть, содержит ли value некоторую комбинацию элементов из обоих списков, чтобы позже работать с этим. Можно ли это сделать за один шаг: что-то вроде этого:
for (i in 1:length(value)){
    if (str_detect(value[i],(city[j]))) == TRUE && str_detect(value[i],(school[j]))) == TRUE){
                   .............................................
    }
}
2 2

2 ответа:

Попробуйте это:

library("stringr")

city <- c("Madrid", "London", "Paris", "Sofia", "Cairo", "Detroit", "New York")
school <- c("Law", "Mathematics", "PoliSci", "Economics")
value <- c(
  "Rey Juan Carlos Law Dept, Madrid",
  "New York University, Center of PoliSci Studies",
  "Los Angeles, CALTECH",
  "London, Physics",
  "London, Mathematics"
      )

for (v in value)
{
  if (sum(str_detect(v, city)) > 0 & sum(str_detect(v, school)) > 0)
  {
    print (v)
  }
}

При выполнении он напечатает те, которые имеют общий элемент с городом и школой:

[1] "Rey Juan Carlos Law Dept, Madrid"
[1] "New York University, Center of PoliSci Studies"
[1] "London, Mathematics"

Эта проблема похожа на ту, над которой я работал. Для моих целей необходимо иметь возвращенный фрейм данных, который сохраняет структуру исходного входного сигнала.

Это может быть справедливо и для вас тоже. Таким образом, я изменил отличное решение от @rbm следующим образом:

library("stringr")

cityList <- c("Madrid", "London", "Paris", "Sofia", "Cairo", "Detroit", "New York")
schoolList <- c("Law", "Mathematics", "PoliSci", "Economics")
valueList <- c(
  "Rey Juan Carlos Law Dept, Madrid",
  "New York University, Center of PoliSci Studies",
  "Los Angeles, CALTECH",
  "London, Physics",
  "London, Mathematics"
)


df <- data.frame(value, city=NA, school=NA, stringsAsFactors = FALSE)

i = 0
for (v in value)
{
  i = i + 1
  if (sum(str_detect(v, cityList)) > 0 & sum(str_detect(v, schoolList)) > 0)
  {
    df$city[i] <- schoolList[[which(str_detect(v, schoolList))]]
    df$school[i] <- cityList[[which(str_detect(v, cityList))]]
  } else {
    df$city[i] <- ""
    df$school[i] <- ""
  }
}
print(df)

Это приводит к следующему:

                                          value        city   school
1               Rey Juan Carlos Law Dept, Madrid         Law   Madrid
2 New York University, Center of PoliSci Studies     PoliSci New York
3                           Los Angeles, CALTECH                     
4                                London, Physics                     
5                            London, Mathematics Mathematics   London