我想指出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")))
我想指出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")))
內匹配任何模式,您也可以使用stringi功能stri_detect_fixed()
。它的字符串和模式參數都是矢量化的,速度非常快,並且不會受到將大量行粘貼在一起時可能出現的最大正則表達式字符數的限制(我通過粘貼30k行發現了這種情況, 無效正則表達式錯誤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))
我們一起paste
的「x」列中,用其作爲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))
如果你知道你的模式總是由你不需要正則表達式的逗號分隔。
df$flag <- as.integer(apply(df, 1, function(r) { r[2] %in% strsplit(r[3], ",", fixed=T)[[1]] }))
謝謝!這兩個選項都很實用並且運行速度很快。由於NA處理,我終於使用了應用程序。 – ronencozen