[英]Test two columns of strings for match row-wise in R
假設我有兩列字符串:
library(data.table)
DT <- data.table(x = c("a","aa","bb"), y = c("b","a","bbb"))
對於每一行,我想知道 x 中的字符串是否存在於 y 列中。 循環方法是:
for (i in 1:length(DT$x)){
DT$test[i] <- DT[i,grepl(x,y) + 0]
}
DT
x y test
1: a b 0
2: aa a 0
3: bb bbb 1
有沒有向量化的實現? 使用grep(DT$x,DT$y)
只使用 x 的第一個元素。
你可以簡單地做
DT[, test := grepl(x, y), by = x]
或mapply
( Vectorize
實際上只是mapply
的包裝器)
DT$test <- mapply(grepl, pattern=DT$x, x=DT$y)
謝謝大家的回復。 我已經對它們進行了基准測試,並得出以下結論:
library(data.table)
library(microbenchmark)
DT <- data.table(x = rep(c("a","aa","bb"),1000), y = rep(c("b","a","bbb"),1000))
DT1 <- copy(DT)
DT2 <- copy(DT)
DT3 <- copy(DT)
DT4 <- copy(DT)
microbenchmark(
DT1[, test := grepl(x, y), by = x]
,
DT2$test <- apply(DT, 1, function(x) grepl(x[1], x[2]))
,
DT3$test <- mapply(grepl, pattern=DT3$x, x=DT3$y)
,
{vgrepl <- Vectorize(grepl)
DT4[, test := as.integer(vgrepl(x, y))]}
)
結果
Unit: microseconds
expr min lq mean median uq max neval
DT1[, `:=`(test, grepl(x, y)), by = x] 758.339 908.106 982.1417 959.6115 1035.446 1883.872 100
DT2$test <- apply(DT, 1, function(x) grepl(x[1], x[2])) 16840.818 18032.683 18994.0858 18723.7410 19578.060 23730.106 100
DT3$test <- mapply(grepl, pattern = DT3$x, x = DT3$y) 14339.632 15068.320 16907.0582 15460.6040 15892.040 117110.286 100
{ vgrepl <- Vectorize(grepl) DT4[, `:=`(test, as.integer(vgrepl(x, y)))] } 14282.233 15170.003 16247.6799 15544.4205 16306.560 26648.284 100
除了語法上最簡單之外,data.table 解決方案也是最快的。
您可以將grepl
函數傳遞給應用函數,以對數據表的每一行進行操作,其中第一列包含要搜索的字符串,第二列包含要搜索的字符串。這應該為您的問題提供矢量化解決方案.
> DT$test <- apply(DT, 1, function(x) as.integer(grepl(x[1], x[2])))
> DT
x y test
1: a b 0
2: aa a 0
3: bb bbb 1
您可以使用Vectorize
:
vgrepl <- Vectorize(grepl)
DT[, test := as.integer(vgrepl(x, y))]
DT
x y test
1: a b 0
2: aa a 0
3: bb bbb 1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.