2017-02-20 82 views
0

有沒有更好更快的方式實現下面? 基本上,我正在尋找(搜索)數據框中的模式。在R的向量模式搜索

以下適用於我。但我無法調整它。時間複雜性是我真正關心的。

searchPattern <- function(ls, pattern){ 
    sapply(ls, function(x) { 
    tmp <- all(table(x)[names(table(pattern))]>=table(pattern)) 
    ifelse(is.na(tmp),FALSE,tmp) 
    }) 
    } 

pattern <- c(5,1) 
df <- list(1,c(1,7,4,5),c(6,5,1,1),5:10,c(5,5,1,1)) 
df 
searchPattern(df,pattern) 

結果是一個邏輯向量:

[1] FALSE TRUE TRUE FALSE TRUE 

在這個例子中的模式僅僅是c(5,1),但循環得到不同的模式,如在此基礎上我揹着1,c(1,7,4,5),c(6,5,1,1),5:10,c(5,5,1,1)

稍後再進行其他轉換。什麼是理想和快速的方式來做到這一點? 任何建議表示讚賞。

+0

也許像'vapply(DF,函數(x)的長度(相交(X,圖案))==長度(模式) ,邏輯(1L))'。 – A5C1D2H2I1M1N2O1R2T1

+0

使用'purrr'包中的'map'函數來提高效率:'map(df,function(x)length(intersect(pattern,x))== length(pattern))'。你也可以使用基礎Map:Map(函數(x)長度(intersect(pattern,x))==長度(pattern),df)'。 – Abdou

+0

Thx。但是函數應該返回'[1] FALSE FALSE TRUE FALSE TRUE',用於'pattern <-c(5,1,1)'而不是'[1] FALSE FALSE FALSE FALSE FALSE' –

回答

0

我打算假設你正在處理正整數。您根據評論提出的解決方案不正確。

例子:

x <- c(5, 1, 1) 
test <- list(c(1, 5, 1, 1), c(1, 5), c(5, 1, 1), c(6, 1, 6, 5, 1, 5), c(1, 1, 1)) 

rec <- function(ll, patt) vapply(ll, function(x) sum(x %in% patt) >= length(patt), logical(1L)) 

rec(test, x) 
## [1] TRUE FALSE TRUE TRUE TRUE 

這裏有一個工作(這裏的「作品」 ==「現有功能的輸出相匹配」)功能。它使用tabulate而不是table,這可以相當快。

sp <- function(ll, patt) { 
    xt <- tabulate(patt) 
    xu <- unique(patt) 
    vapply(ll, function(z) all(tabulate(z, max(xu))[xu] >= xt[xu]), logical(1L)) 
} 

sp(test, x) 
## [1] TRUE FALSE TRUE TRUE FALSE 

測試出來的東西較大:

set.seed(2) 
y <- replicate(100, sample(8, sample(4:10, 1), TRUE), FALSE) 
x <- c(5, 1, 1) 

library(microbenchmark) 
microbenchmark(sp(y, x), searchPattern(y, x)) 
## Unit: microseconds 
##     expr  min  lq  mean  median  uq  max neval 
##    sp(y, x) 267.134 295.096 312.9538 311.1815 323.369 485.269 100 
## searchPattern(y, x) 24709.732 25218.143 26663.5091 25737.1475 28478.559 31324.695 100 

identical(sp(y, x), searchPattern(y, x)) 
## [1] TRUE 
+0

你是絕對正確的。我願意給出它必須遵循的所有條件。 Thax抽出時間把它放在一起。我會對大數據進行測試,並讓你表現 –