Сравнение строк на основе условий с использованием grepl и ifelse - PullRequest
0 голосов
/ 04 июля 2018

У меня есть датафрейм df, упомянутый ниже.

a <- c(1:6)
b <- c("Audi,BMW,Skoda, Rackets,Toy,Football",
       "Suzuki,Kawasaki,Ducati,Aprilia,Baseball, Rugby",
       "Mazda, Ford, chevrolet,Mercedes,Gloves,Helmet",
       "Lemon,Yamaha,Table,Kawasaki,Chair,Fruits", 
       "Ford, chevrolet,Bread,Ducati,Tesla,Hyundai",
       "Honey,Apple,Alcohol,cake,Sweets, Mango")
       df <- data.frame(a,b)

*

У меня также есть два списка с маркой автомобилей и мотоциклов.

cars <- c("Audi","BMW","Ford","Skoda","Mazda","chevrolet","Mercedes","Volkswagen","Tesla","Hyundai","Lamborghini","Mini-Cooper","Lexus")
motorbike <- c("Yamaha","Suzuki","Kawasaki","Harley-Davidson","Ducati","Aprilia","KTM", "Triumph","Piaggio","Hyosung","Vespa","MV-Agusta")

Я использовал grepl с ifelse, чтобы сопоставить слова из списка двух в df $ b и назначить значение каждой строке, если они совпадают.

df$c<-ifelse(grepl(paste(cars, collapse="|"), df$b), "cars",
      ifelse(grepl(paste(motorbike, collapse="|"),df$b), "bikes","others"))

Теперь я хочу поставить условие, что если в каждой строке совпадают 4 или более 4 слов, то только тогда значение (машина, велосипед) присваивается в df $ c. Я хочу, чтобы мой df был таким:

structure(list(a = 1:6, b = structure(c(1L, 6L, 5L, 4L, 2L, 3L
), .Label = c("Audi,BMW,Skoda, Rackets,Toy,Football", "Ford, chevrolet,Bread,Ducati,Tesla,Hyundai", 
"Honey,Apple,Alcohol,cake,Sweets, Mango", "Lemon,Yamaha,Table,Kawasaki,Chair,Fruits", 
"Mazda, Ford, chevrolet,Mercedes,Gloves,Helmet", "Suzuki,Kawasaki,Ducati,Aprilia,Baseball, Rugby"
), class = "factor"), c = c("others", "bikes", "cars", "others", 
"cars", "others")), row.names = c(NA, 6L), class = "data.frame") 

1 Ответ

0 голосов
/ 04 июля 2018

Это помогает? Конечно, вы можете удалить столбцы суммами и автомобилями. И вы ожидаете, что это никогда не произойдет, если у вас есть> 3 машины и> 3 двигателя в цепочке? Основываясь на комментариях, я обновил свой ответ.

library(stringr)
df$amountcars <- str_count(df$b, paste(cars, collapse="|"))
df$amountmotors <- str_count(df$b, paste(motorbike, collapse="|"))



df$c <- ifelse(df$amountcars > 3 & df$amountcars > df$amountmotors, "cars", ifelse(df$amountmotors > 3 & df$amountmotors > df$amountcars, "bikes", "others"))
df

  a                                              b amountcars amountmotors      c
1 1           Audi,BMW,Skoda, Rackets,Toy,Football          3            0 others
2 2 Suzuki,Kawasaki,Ducati,Aprilia,Baseball, Rugby          0            4  bikes
3 3  Mazda, Ford, chevrolet,Mercedes,Gloves,Helmet          4            0   cars
4 4       Lemon,Yamaha,Table,Kawasaki,Chair,Fruits          0            2 others
5 5     Ford, chevrolet,Bread,Ducati,Tesla,Hyundai          4            1   cars
6 6         Honey,Apple,Alcohol,cake,Sweets, Mango          0            0 others

На основе комментариев, если у вас есть как 9 строк: Сначала создайте все векторы со строками:

cars <- c("Audi","BMW","Ford","Skoda","Mazda","chevrolet","Mercedes","Volkswagen","Tesla","Hyundai","Lamborghini","Mini-Cooper","Lexus")
motorbike <- c("Yamaha","Suzuki","Kawasaki","Harley-Davidson","Ducati","Aprilia","KTM", "Triumph","Piaggio","Hyosung","Vespa","MV-Agusta")

Затем поместите их в список и добавьте имена

list1 <- list(cars, motorbike)
names(list1) <- c("cars", "motorbike")

Наконец, запустите этот код:

df$d <- 
ifelse(apply(sapply(list1, function(x) str_count(df$b, paste0(x, collapse = "|"))), 1, max) > 3,
apply(sapply(list1, function(x) str_count(df$b, paste0(x, collapse = "|"))), 1, function(x) names(list1)[which.max(x)]),
"others")

По сути, он вычисляет максимальное количество строк по одному из векторов, а если он больше 3, ему присваивается соответствующее имя, в противном случае он присваивает «другие».

...