2015-11-01 4 views
-1

Я хотел бы указать, если x содержится в y, предпочтительно без использования цикла. Я попробовал следующее, но он выдает ошибку.Частичное соответствие строк по двум векторам

df$flag <- ifelse(grep(df$x, df$y), 1, 0) 

Вот пример:

df <- data.frame(id=seq(1,3,1),x=c("abc","efd","xyz"), y=(c("abc,efd","hig,mno","abc,xyz"))) 

ответ

3

Вы можете также использовать STRINGI функцию stri_detect_fixed(). Он векторизован как по его строковым, так и по шаблонным аргументам, очень быстрый и не будет ограничен максимальным количеством символов регулярного выражения, которое может возникнуть, вставив вместе большое количество строк (я нашел это, вставив 30 тыс. Строк, что возвращает a недействительное регулярное выражение ошибка в grepl()).

df$flag <- as.integer(stringi::stri_detect_fixed(df$y, df$x)) 
df 
# id x  y flag 
# 1 1 abc abc,efd 1 
# 2 2 efd hig,mno 0 
# 3 3 xyz abc,xyz 1 

Другая альтернатива, хотя цикл, является mapply()

df$flag <- as.integer(mapply(grepl, df$x, df$y)) 
+0

Спасибо! оба варианта функциональны и работают довольно быстро. Я закончил использование mapply из-за обработки NA. – ronencozen

1

Мы paste столбца «х» вместе, использовать его в качестве pattern, чтобы найти те элементы, которые соответствуют шаблону в колонке «Y». grepl возвращает логический вектор, который может быть принудительно преобразован в двоичный код путем обертывания +.

df$flag <- +(grepl(paste0(df$x, collapse='|'), df$y)) 
df 
# id x  y flag 
#1 1 abc abc,efd 1 
#2 2 efd hig,mno 0 
#3 3 xyz abc,xyz 1 

Просто чтобы быть в безопасности, мы можем также использовать границу слова, так что он не будет соответствовать какой-либо модели в слове

+(grepl(paste0('\\b(', paste0(df$x, collapse='|'), ')\\b'), df$y)) 
0

Если вы знаете, что ваши рисунки всегда разделены запятой, вам не нужно регулярное выражение.

df$flag <- as.integer(apply(df, 1, function(r) { r[2] %in% strsplit(r[3], ",", fixed=T)[[1]] })) 
Смежные вопросы