2017-04-12 7 views
2

Ich habe folgende Datentabellen:Join auf Pattern-Matching

> measures 
    source  measure 
1: my123 0.08130182 
2: 123my -1.45285168 
3: your123 -0.30460771 
4: 123your 0.94670380 
5: 12your3 -0.54728546 
> sources 
      name pattern 
1: My Source  my 
2: Your Source your 

erstellt

measures <- data.table(source=c('my123', '123my', 'your123', '123your', '12your3'), measure=rnorm(5)) 
sources <- data.table(name=c('My Source', 'Your Source'), pattern=c('my', 'your')) 

mit Ich möchte in der Lage sein, auf like(measures.source, sources.pattern) beizutreten. Gibt es eine gute Möglichkeit, dies zu tun (ohne Cross-Join und Filterung nicht übereinstimmenden Zeilen. Dies wird auf meinem Datensatz nicht praktikabel sein)

Ich kann dies in SQL (PostgreSQL, siehe unten), aber ich Ich frage mich, gibt es eine Möglichkeit, es in Rs data.table oder irgendwelche Pläne zu tun, mehr benutzerdefinierte Joining-Funktionalität in der Zukunft einzuführen.

drop table if exists measures; 
create table measures as (select * from (values 
    ('my123', 0.08130182), 
    ('123my', -1.45285168), 
    ('your123', -0.30460771), 
    ('123your', 0.94670380), 
    ('your123', 0.94670380) 
)t(source, measure)); 

drop table if exists sources; 
create table sources as (select * from (values 
    ('My Source', 'my'), 
    ('Your Sources', 'your') 
)t(name, pattern)); 

select * from measures join sources on measures.source ~ sources.pattern; 

und dies gibt die benötigt:

source | measure |  name  | pattern 
--------+-------------+--------------+--------- 
my123 | 0.08130182 | My Source | my 
123my | -1.45285168 | My Source | my 
your123 | -0.30460771 | Your Sources | your 
123your | 0.94670380 | Your Sources | your 
your123 | 0.94670380 | Your Sources | your 
+0

Ich nehme an, Sie wirklich 'gemeint measures.source' nicht' measures.name' – G5W

+1

Es ist ein offenes FR für diese https://github.com/Rdatatable/data.table/issues/1431 mit hoher Priorität gekennzeichnet, fwiw. – Frank

+0

@ G5W danke, ich reparierte es – nikola

Antwort

0

Ich bin nicht sicher, ob dies unter „unpraktisch“ fällt oder nicht, aber das wird es tun ... und für Ihre Zwecke mit komplexeren Pattern Matching Stringi wird den Collator behandeln.

> rbind.pages(lapply(1:nrow(measures), function(i){ 
     matched_slice <- which(stri_detect_regex(measures[i,1],sources$pattern)) 
     data.frame(measures[i,], sources[matched_slice, ]) 
    })) 
    source  measure  name pattern 
1 my123 0.75119183 My Source  my 
2 123my 0.55344334 My Source  my 
3 your123 -0.03498414 Your Source your 
4 123your 0.09364795 Your Source your 
5 12your3 0.47537732 Your Source your 

Und für größere Datenmengen führen dies mit parallel::mclapply oder für die data.table -ish Weg:

rbindlist(lapply(1:nrow(measures), function(i){ 
    matched_slice <- which(stri_detect_regex(measures[i,1],sources$pattern)) 
    cbind(measures[i,], sources[matched_slice, ]) 
})) 
+0

Danke, das ist leider immer noch nicht machbar für mich, weil es zu lange auf dem Datensatz, an dem ich arbeite, dauert. – nikola