2014-10-29 29 views
1

我想開始使用data.table而不是dplyr,因爲我必須加快計算速度。 現在我的組中每個元素的代碼都使用分組列的值。 但data.table會丟棄它。如何在data.table中獲取用戶定義函數中的分組列的值

y v 
1: 1 1 
2: 3 2 
3: 6 3 

該組的第一個元素:例如當x值從瀏覽器查詢

g <- function(x) { 
    browser() 
} 

DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 

DT[,list(a = g(.SD)), keyby="x"] 

給出了這樣的。

有沒有什麼辦法可以讓我爲g()中的每個組獲得x的值?

更新: 我正在使用一個函數,其中公式取決於組,例如,

g <- function(data) { 
    if (x == "a") { 
     return(y-v) 
    } else { 
     return(v-y) 
    } 
} 
+0

我懷疑,問什麼是如何引用分組變量的「J」 -expression內'[.data.table',但正在使用的功能沒有在通信的特定目的對於這個請求。 – 2014-10-29 17:47:12

+0

感謝@BondedDust的編輯。 kismsu,也很有可能獲得分組變量。不過,如果你展示你的實際任務是什麼以獲得更好的想法(在寫答案之前),它會有所幫助。 – Arun 2014-10-29 17:49:22

回答

2

首先,假設這或多或少是你的函數(意思是:這是短期和/或類似的),我會直接在j做到這一點,像這樣:

DT[, .(a = (y-v) * (2L*(x=="a") - 1L)), by="x"] 
# or if it's too cryptic 
DT[, .(a = if (x=="a") y-v else v-y), by="x"] 

現在假設你的功能更復雜,至少有兩種方法可以解決這個問題。

  • 首先,默認情況下,來自分組列的值長度爲1。所以,可以編寫一個函數,一個額外的參數,它是該組值如下:

    foo <- function(dt, grp) { 
        if (grp == "a") dt[, y-v] 
        else dt[, v-y] 
    } 
    DT[, .(a = foo(.SD, x)), by="x"] 
    

    這裏grp將長度-1(如上文解釋)。

  • 使用.SDcols也可以在.SD中添加分組列。

    foo <- function(dt) { 
        if (dt$x[1L] == "a") dt[, y-v] 
        else dt[, v-y] 
    } 
    DT[, .(a = foo(.SD)), by="x", .SDcols = c("x", "y", "v")] 
    

    雖然我更喜歡第一種方法,因爲它不涉及不必要創建只具有一個獨特的價值一個額外的列。

+1

感謝您的回答。我還發現,我可以發送.BY功能與分組值的列表。 – kismsu 2014-10-30 07:07:08

相關問題