识别包含字符串的行的最快方法



我有一个字符串的数据框架,尺寸为30列乘500万行。我想识别包含任何预定义字符串列表的行。有没有比下面的appley((+any((方法更快的方法?

这是一个可重复的例子。请注意,本例中的字符串是随机数,但在我的应用程序中,它们是实际的字符串。

m <- 5E6
n <- 30
# Generate a matrix with random strings
A <- as.data.frame( matrix(sprintf('%.2f', sample.int(1000,m*n, replace=T)), nrow=m, ncol=n), stringsAsFactors=F)
# Generate a list of strings I want to find
search_strings <- sprintf('%.2f', sample.int(1000,30, replace=T))
#Which rows contain any of those strings?
system.time(findRows <- apply(A, 1, function (r) any ( r %in% search_strings)))

使用以下答案显著改进:

# Original
R> system.time(findRows <- apply(A, 1, function (r) any ( r %in% search_strings)))
user  system elapsed
33.439   2.748  36.739
# @Ronak's answers
R> system.time(findRows <- Reduce(`|`, lapply(A, `%in%`, search_strings)))
system.time(findRows <- rowSums(sapply(A, `%in%`, search_strings)) > 0)
user  system elapsed
5.225   0.790   6.252
R> system.time(findRows <- rowSums(sapply(A, `%in%`, search_strings)) > 0)
user  system elapsed
5.426   1.153   6.715
# @Ian's answer
R> system.time(A[A[,lapply(.SD,function(x){x %chin% search_strings})][,rowSums(.SD) > 0],])
user  system elapsed
4.542   0.445   5.033

apply,尤其是在大数据帧上更慢。

使用lapplysapply:在基R中尝试这两种替代方法

#lapply
findRows <- Reduce(`|`, lapply(A, `%in%`, search_strings))
#sapply
findRows <- rowSums(sapply(A, `%in%`, search_strings)) > 0

data.table怎么样?

library(data.table)
setDT(A)
findRows <- A[,lapply(.SD,function(x){x %chin% search_strings})][,rowSums(.SD) > 0]

最新更新