2016-06-08 72 views
3

[data.table_1.9.6] 問題的背景是我試圖在星型模式中構建類似olap的查詢功能像數據佈局,即一個大的事實表和幾個元表。我建立一個函數來包裹data.table聯接,然後聚集在鏈這樣:r data.table圍繞ad-hoc連接的函數包裝器(在鏈中有聚合)

# 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] 

我的猜測是,我必須提供「的」參數的即席以不同的方式。我嘗試了= c(get(x_key)= meta_key),但他抱怨意外的括號。我可以使用setkey版本的函數,但我不知道這是否有效,因爲該函數可以在不同的元表上工作,這取決於使用哪個屬性來聚合,並因此不斷重新設置密鑰。或者是setkey總是首選?實際的事實表(這裏是x)有> 30萬行。

+2

您可能要檢查[data.cube(https://github.com/jangorecki/data.cube)封裝定義OLAP多維數據集R數據類型的基礎上,集data.tables。在這個包裏面有一個'cube'類,它是星型模式建模的。在devel分支* data.cube-oop *中有一個新的'data.cube'類,它是星型和雪花型架構的混合體,在[this SO question]中進行了描述(https://stackoverflow.com/questions/35472639/星型模式標準化維度,非規範化的層次結構級別的密鑰)。它會自動將子集合到可用維度,並將多維數據集中的數據標準化。 – jangorecki

+0

@jangorecki:我知道你的包裹。已經在過去看過它。無論如何感謝提示!如果不被企業IT阻止,我也很樂意通過它的github源代碼。但有沒有data.table唯一的實現? – Triamus

+2

實際的上游回購是在[gitlab.com/jangorecki/data.cube](https://gitlab.com/jangorecki/data.cube)上,所以你可以試試。實現基於'data.table'和[big.data.table](https://github.com/jangorecki/big.data.table)用於事實表(目前只有部分用於'cube'類)。後者允許在多臺機器上分配事實表,消除內存限制並允許並行查詢,從而能夠高效地處理OLAP大數據。 – jangorecki

回答

2

所有你需要做的就是構建一個帶有正確標籤的矢量。下面是這樣做的一種方式:

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

您是否對功能設計有意見,即setkey是否優於ad-hoc密鑰? – Triamus

+2

@Triam現在我幾乎只用'on'。它更加靈活,我喜歡在每次操作中知道自己在做什麼,而不是在代碼的其他部分使用'setkey',然後必須記住我已經完成了。現在唯一使用'setkey'的情況是,如果我需要在同一個鍵上連續執行多個連接/查找。 – eddi