2013-10-09 72 views
8

表情:我打了這個問題的確切問題並不適用於最新版本的數據表。如果您想按照標題中的描述進行操作,請查看包裝常見問題解答1.6 OK, but I don’t know the expressions in advance. How do I programatically pass them in?中的相應問題。data.table`:=`分配與動態輸入(現有列)和輸出(新列名)

我看到an answer闡釋如何構建表達在

DT[,j=eval(expr)] 

我用這與工作分配進行評價,```:=`(mycol = my_calculation)``,我想知道...

  • 如何動態地指定名稱「mycol」?
  • 讓「my_calculation」採用動態確定的一組列的正確方法是什麼?

「動態」,我的意思是「在我爲我的expr編寫代碼後確定」。

新的例子

編輯:爲了更好地說明問題,這裏是另一個例子。查看編輯歷史記錄以查看原件。

require(data.table) 
require(plyr) 
options(datatable.verbose=TRUE) 
DT <- CJ(a=0:1,b=0:1,y=2) 

# setup: 
expr <- as.quoted(paste(expression(get(col_in_one)+get(col_in_two))))[[1]] 

# usage: 
col_in_one <- 'a' 
col_in_two <- 'b' 
col_out <- 'bah' 
DT[,(col_out):=eval(expr)] # fails, should take the form j=eval(expr) 

我想保持安裝和使用階段分開,所以我的代碼更易於維護。我的真實表情比這個例子更混亂(它只是選擇一列)。

問題

第一個問題:我怎樣才能使分配到列, 「col_out」,動態?我的意思是:我想在動態指定「cols_in_ *」和「col_out」。

我試圖創造「expr的」各種表情,但as.quoted拋出關於不把某些東西給=符號左側的錯誤。

第二個問題:我怎樣才能避免對使用get的警告?

警告建議使用.SDcols,讓[.data.table知道我正在使用哪些列。但是,如果我使用.SDcols參數,另一個警告說除非使用.SD,否則沒有意義。

暫定解決方案

我到目前爲止的解決方案是......

# Ricardo + eddi: 
expr2 <- as.quoted(paste(expression(`:=`(
    Vtmp=.SD[[col_in_one]]+.SD[[col_in_two]]))))[[1]] 

# usage 
col_in_one <- 'a' 
col_in_two <- 'b' 
col_out <- 'bah' 
DT[,eval(expr2),.SDcols=c(col_in_one,col_in_two)] 
setnames(DT,'Vtmp',col_out) 

這還牽扯到做兩步操作和跟蹤「Vtmp」的小煩惱,所以第一個問題還是部分打開。

+0

相關:HTTP:/ /stackoverflow.com/questions/15790743/data-table-meta-programming/15791747#15791747 –

回答

8

也許我不明白這個問題很好,但做到這一點就夠了:

DT[, (col_out) := .SD[[col_in_one]]+.SD[[col_in_two]], 
    .SDcols = c(col_in_one,col_in_two)] 
DT 
# a b y bah 
#1: 0 0 2 0 
#2: 0 1 2 1 
#3: 1 0 2 1 
#4: 1 1 2 2 

要回答編輯的問題,以獲得eval工作,使用.SD作爲環境:

DT[, (col_out) := eval(expr, .SD)] 

而且,看到這個問題,並沒有更新 - eval and quote in data.table

+0

像這樣的東西可能沒問題,但我寧願保留我的表情,並將其用於(可能在多個地方)分開。此外,這應該是緩慢的,因爲你正在創建'.SD'並且爲'th'調用'[.data.table',對吧? .SD [[x]]比'get(x)'更好嗎? ......好的,裏卡多的鏈接解釋說,它比「get」更好。 – Frank

+0

@Frank抱歉,我不認爲我理解你想要做什麼 - 一個更簡單的例子集中在這個問題上會有所幫助。 Re' get':使用帶'.SDcols'的'.SD'比'get'好,因爲在第一種情況下,只有'.SDcols'中的列被構造爲'.SD';因爲這裏使用了所有的'.SD',所以使用'.SD'應該沒有任何開銷(但它可能更好地完成整個reduce業務) – eddi

+0

感謝您提供它。我添加了一些粗體文本(我討厭這樣做)並更改了示例。我將編輯你的答案來匹配新的例子。 – Frank

5

最簡單的方法是在評估表達式之後設置它。畢竟,執行的時間是恆定的,幾乎爲0。

someDummyVar <- "tempColName_XCWF5D" 
DT [, (someDummyVar) := eval(expr) ] 

setnames(DT, someDummyVar, RealColumnName) 

對於問題二:不要打開詳細的警告,你不會得到詳細的警告;)

options(datatable.verbose=FALSE) 

至於Reduce :嘗試張貼,作爲一個獨立的和簡化的問題,以便更容易跟着你在做什麼(外面的eval問題)

+0

+1。對,是真的;我只是不希望維護兩倍的代碼來運行該操作。我想我可以將它們捆綁到一個函數中。關於#2的任何想法 - 避免「獲取」警告;或#3 - 給予'eval'線性表達式本身,而不是'Reduce'它必須轉換... – Frank

+0

@Frank,看看上面鏈接的問題 –

+0

啊,謝謝,我正在尋找這個問題。 – Frank