2016-06-08 9 views
3

[data.table_1.9.6] Hintergrund der Frage ist, dass ich versuche, Olap-ähnliche Abfrage-Features in einem Sternschema zu erstellen Ähnliches Datenlayout, dh eine große Faktentabelle und mehrere Meta-Tabellen. Ich baue eine Funktion Wrapper um data.table wie dies durch eine Aggregation in einer Kette gefolgt join:r data.table Funktions-Wrapper um Ad-hoc Join (mit Aggregation in einer Kette)

# dummy data 
dt1 = data.table(id = 1:5, x=letters[1:5], a=11:15, b=21:25) 
dt2 = data.table(k=11:15, z=letters[11:15]) 

# standard data.table query with ad-hoc key -> works fine 
dt1[dt2, c("z") := .(i.z), with = F, 
    on = c(a="k")][, .(m = sum(a, na.rm = T), 
        count = .N), by = c("z")] 

# wrapper function with setkey -> works fine 
agg_foo <- function(x, meta_tbl, x_key, meta_key, agg_var) { 
    setkeyv(x, x_key) 
    setkeyv(meta_tbl, meta_key) 
    x[meta_tbl, (agg_var) := get(agg_var)][,.(a_sum = sum(a, na.rm=T), 
              count = .N), 
             by = c(agg_var)] 
    x[, (agg_var) := .(NULL)] 
    } 

# call function (works fine) 
agg_foo(x=dt1, meta_tbl=dt2, x_key="a", meta_key="k",agg_var="z") 

# wrapper function with ad-hoc key -> does not work 
agg_foo_ad_hoc <- function(x, meta_tbl, x_key, meta_key, agg_var) { 
    x[meta_tbl, (agg_var) := get(agg_var), 
    on = c(x_key = meta_key)][,.(a_sum = sum(a, na.rm=T), 
           count = .N), by = c(agg_var)] 
    x[, (agg_var) := .(NULL)] 
    } 

# call function (causes error) 
agg_foo_ad_hoc(x=dt1, meta_tbl=dt2, x_key="a", meta_key="k",agg_var="z") 

Error in forderv(x, by = rightcols) : 
    'by' value -2147483648 out of range [1,4] 

meine Vermutung ist, dass ich die Ad-hoc „auf“ Parameter in einer anderen Art und Weise zur Verfügung stellen muß. Ich habe versucht an = c (get (x_key) = meta_key), aber dann klagt er über unerwartete Klammern. Ich könnte mit der Setkey-Version der Funktion arbeiten, die funktioniert, aber ich frage mich, ob dies effizient ist, da die Funktion abhängig von dem für die Aggregation verwendeten Attribut an verschiedenen Meta-Tabellen arbeitet und somit den Schlüssel ständig neu setzt. oder ist der setkey immer zu bevorzugen? Tatsächliche Faktentabelle (x hier) hat> 30 Millionen Zeilen.

+2

Sie können [data.cube] überprüfen möchten (https://github.com/jangorecki/data.cube) Paket, das OLAP-Cube-R-Datentyp definiert, basierend auf dem Set von data.tables. Im Paket gibt es eine 'Würfel'-Klasse, die ein Sternschema ist. In devel branch * datacube.cube-oop * gibt es eine neue 'data.cube'-Klasse, die eine Mischung aus Stern- und Schneeflocken-Schema ist, beschrieben in [dieser SO-Frage] (https://stackoverflow.com/questions/35472639/ sternschema-normalisierte-dimensionen-denormalisierte-hierarchy-level-keys). Es aggregiert automatisch zu verfügbaren Dimensionen und hält die Daten in Cube normalisiert. – jangorecki

+0

@jangorecki: Ich weiß von Ihrem Paket. hat schon in der Vergangenheit nachgeschaut. Danke für den Tipp trotzdem! Ich würde auch gern durch die Github-Quelle gehen, wenn sie nicht von der IT des Unternehmens blockiert würde. Aber gibt es eine Implementierung von data.table only? – Triamus

+2

Der eigentliche Upstream-Repo ist auf [gitlab.com/jangorecki/data.cube](https://gitlab.com/jangorecki/data.cube), so dass Sie es dort versuchen können. Die Implementierung basiert auf 'data.table' und [big.data.table] (https://github.com/jangorecki/big.data.table) für die Faktentabelle (und nur teilweise für die Klasse' cube' bisher). Letzteres erlaubt es, die Faktentabelle auf mehrere Maschinen zu verteilen, die Speichergrenzen zu entfernen und parallelisierte Abfragen zu ermöglichen, die in der Lage sind, OLAP-Big-Data effizient zu verarbeiten. – jangorecki

Antwort

2

Alles, was Sie tun müssen, ist einen Vektor mit korrekten Etiketten zu konstruieren. Hier ist eine Möglichkeit zu tun, dass:

agg_foo_ad_hoc <- function(x, meta_tbl, x_key, meta_key, agg_var) { 
    x[meta_tbl, (agg_var) := get(agg_var), 
    on = setNames(meta_key, x_key)][,.(a_sum = sum(a, na.rm=T), 
             count = .N), by = c(agg_var)] 
    x[, (agg_var) := .(NULL)] 
} 
+0

Haben Sie eine Meinung zum Funktionsdesign, d. H. Ob setkey einem Ad-hoc-Schlüssel vorzuziehen ist? – Triamus

+2

@Triam heutzutage benutze ich fast ausschließlich "on". Es ist flexibler und ich mag es zu wissen, was ich bei jeder Operation mache, im Gegensatz zu "setkey" in einem anderen Teil des Codes und dann daran erinnern, dass ich das getan hatte. Der einzige Fall, in dem ich 'setkey' verwenden würde, ist, wenn ich mehrere Joins/Lookups in einer Reihe auf demselben Schlüssel machen muss. – eddi

Verwandte Themen