2015-10-04 6 views
21

Das fastmatch Paket eine viel schnellere Version von match zum wiederholten Treffern (zB in einer Schleife) implementiert:Faster% in% Operator

set.seed(1) 
library(fastmatch) 
table <- 1L:100000L 
x <- sample(table, 10000, replace=TRUE) 
system.time(for(i in 1:100) a <- match(x, table)) 
system.time(for(i in 1:100) b <- fmatch(x, table)) 
identical(a, b) 

Gibt es eine ähnliche Implementierung für %in% wiederholt ich Lookups zu beschleunigen verwenden könnte ?

Antwort

27

Blick auf die Definition von %in%:

R> `%in%` 
function (x, table) 
match(x, table, nomatch = 0L) > 0L 
<bytecode: 0x1fab7a8> 
<environment: namespace:base> 

Es ist einfach, Ihre eigene %fin% Funktion zu schreiben:

`%fin%` <- function(x, table) { 
    stopifnot(require(fastmatch)) 
    fmatch(x, table, nomatch = 0L) > 0L 
} 
system.time(for(i in 1:100) a <- x %in% table) 
# user system elapsed 
# 1.780 0.000 1.782 
system.time(for(i in 1:100) b <- x %fin% table) 
# user system elapsed 
# 0.052 0.000 0.054 
identical(a, b) 
# [1] TRUE 
+0

aber Fastmatch es nicht, wenn man gegen NA übereinstimmen funktioniert, tut Basisspiel. – skan

+0

Wo ist es ?. Ist "https://github.com/s-u/fastmatch" der richtige Link ?. Es scheint nicht vor langer Zeit aktualisiert worden zu sein. – skan

+0

Ich habe% fin% und fmatch mit lapply probiert, um auf jede Spalte einer großen data.frame oder data.table zu passen und kann keinen großen Unterschied in der Geschwindigkeit bemerken. – skan

3

Spiel fast immer besser gemacht, indem beide Vektoren in Datenrahmen setzen und Zusammenführung (siehe Verschiedene Verbindungen von dplyr)

Zum Beispiel würde so etwas wie Sie alle Informationen erhalten Sie benötigen:

library(dplyr) 

data = data_frame(data.ID = 1L:100000L, 
        data.extra = 1:2) 

sample = 
    data %>% 
    sample_n(10000, replace=TRUE) %>% 
    mutate(sample.ID = 1:n(), 
     sample.extra = 3:4) 

# join table not strictly necessary in this case 
# but necessary in many-to-many matches 
data__sample = inner_join(data, sample) 

#check whether a data.ID made it into sample 
data__sample %>% filter(data.ID == 1) 

oder left_join, right_join, full_join, semi_join, anti_join, je nachdem, welche Informationen für Sie am nützlichsten ist

+0

Würde es Ihnen etwas ausmachen, dies zu erklären (vorzugsweise mit einem Beispiel enthalten)? In diesem Moment ist Ihre "Antwort" eher ein Kommentar als eine echte Antwort. – Jaap

+0

Siehe bearbeitete Version – bramtayl