Проверка условий и добавление элементов во фрейм данных

#r #dataframe

#r #фрейм данных

Вопрос:

Я пытаюсь разработать функцию, которая позволит мне вводить новые элементы во фрейм данных, а затем проверять, содержат ли они определенные слова.

 df <- data.frame(keyword=c("He drives a Honda", "He goes to Ohio State"), 
        car=c(1,0), school=c(0,1))
df

               keyword car school
     He drives a Honda   1      0
 He goes to Ohio State   0      1
  

В этом фрейме данных car и school являются двоичными значениями, которые содержат 1, если слово из вектора car / school является частью ключевого слова. Если в ключевом слове отсутствует слово, то присваивается 0.

 car <- c("Honda", "Chevy", "Toyota", "Ford")
school <- c("Michigan", "Ohio State", "Missouri")
  

Я хочу использовать функцию для ввода новых ключевых слов во фрейм данных, одновременно повторяя ключевые слова для определенных значений из векторов car и school.

 main <- function(keyword){
    n = strsplit(as.character(keyword), " ")[[1]]
    for( i in keyword ){
       if( any(n==car) ){
          df$car <- c(1)
       }
       if( any(n==school )){
          df$school <- c(1)
    }
}
  

}

Эта функция не завершена и выдает следующую ошибку. Поскольку векторы car и school имеют длину 3, похоже, это приводит к ошибке.

 > main("He likes Ford and goes to Ohio State")            
Warning message:
In n == school :
  longer object length is not a multiple of shorter object length
  

Я также не уверен, как добавить значения 0/1 в df. Для ключевого слова «Ему нравится Ford и он едет в штат Огайо» у меня должно быть 1 как в колонках «автомобиль», так и в колонках «школа».

                               keyword       car          school
                    He drives a Honda        1             0
                He goes to Ohio State        0             1
He likes Honda and goes to Ohio State        1             1
  

Пожалуйста, помогите.
Похоже, ifelse() функция была бы действительно полезна для этой задачи, но я не смог ее должным образом реализовать.

Ответ №1:

Я думаю, что самый простой способ — использовать составное регулярное выражение:

 library(stringr)

car <- c("Honda", "Chevy", "Toyota", "Ford")
school <- c("Michigan", "Ohio State", "Missouri")

car_match <- str_c(car, collapse = "|")
school_match <- str_c(school, collapse = "|")


df <- data.frame(keyword=c("He drives a Honda", 
  "He goes to Ohio State", 
  "He likes Ford and goes to Ohio State"))

main <- function(df) {
  df$car <- str_detect(df$keyword, car_match)
  df$school <- str_detect(df$keyword, school_match)
  df
}
main(df)
  

Комментарии:

1. вау, это очень эффективно. Есть ли способ изменить FALSE / TRUE на 0/1?

2. Вы можете добавить 0 или использовать как.numeric. Но я сомневаюсь, что в этом есть какая-либо необходимость.

Ответ №2:

Несколько незначительных проблем, но их легко устранить с помощью пары %in% . Также вам нужно специальное логическое выражение для учета «Штата Огайо», который отключался strsplit из-за пробела.

 df <- data.frame(keyword=c("He drives a Honda", 
  "He goes to Ohio State", 
  "He likes Ford and goes to Ohio State"),
  car=0, school=0)

main <- function(df) {
  car <- c("Honda", "Chevy", "Toyota", "Ford")
  school <- c("Michigan", "Missouri")
  for (i in 1:nrow(df)) {
    Words = strsplit(as.character(df[i, 'keyword']), " ")[[1]]
    if(any(Words %in% car)) df[i, 'car'] <- 1
    if(any(Words == 'Ohio')) {
      if(Words[which(Words == 'Ohio')   1] == 'State') df[i, 'school'] <- 1
    }   
    if(any(Words %in% school)) df[i, 'school'] <- 1 
  }
  return(df)
}

main(df)

                               keyword car school
1                    He drives a Honda   1      0
2                He goes to Ohio State   0      1
3 He likes Ford and goes to Ohio State   1      1
  

Ответ №3:

Вот версия, которая, я полагаю, будет работать без необходимости указывать каждый поисковый запрос из двух слов вручную, как в случае «Штата Огайо» в решении wkmor1. Хитрость заключается в использовании grep вместо:

 main <- function(str,df){
    carSearch <- unlist(lapply(car,grep,x=str,fixed=TRUE))
    schoolSearch <- unlist(lapply(school,grep,x=str,fixed=TRUE))
    t1 <- length(carSearch) != 0
    t2 <- length(schoolSearch) != 0
    if (t1 | t2){
        newRow <- data.frame(keyword=str,car=ifelse(t1,1,0),
                              school=ifelse(t2,1,0))
        df <- rbind(df,newRow)
        return(df)
    }
}