2013-03-17 85 views
4

我想scale我的data.table中的一個列的子集。有很多這些,我想scale,所以我想避免指定他們所有的名字。沒有被縮放的列,我只想返回原樣。這是我希望能工作,但它不:縮放R中的一列data.table的子集

require(data.table) 
x = data.table(id=1:10, a=sample(1:10,10), b=sample(1:10,10), c=sample(1:10,10)) 
> dput(x) 
structure(list(id = 1:10, a = c(1L, 6L, 10L, 7L, 5L, 3L, 2L, 
4L, 9L, 8L), b = c(4L, 9L, 5L, 7L, 6L, 1L, 8L, 10L, 3L, 2L), 
    c = c(2L, 7L, 5L, 6L, 4L, 1L, 10L, 9L, 8L, 3L)), .Names = c("id", 
"a", "b", "c"), row.names = c(NA, -10L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x1a85d088>) 

sx = x[,c(id, lapply(.SD, function(v) as.vector(scale(v)))), .SDcols = colnames(x)[2:4]] 
    Error in eval(expr, envir, enclos) : object 'id' not found 

有什麼建議嗎?

回答

3
sx = cbind(x[,-(2:4),with=FALSE],data.table(scale(x[,2:4,with=FALSE]))) 

我懷疑,最好是你的工作流將data.table融化爲長格式。

+0

真棒,謝謝!實際上這是工作過程的結束。在此之後的步驟進行迴歸,並且結束它。 – Alex 2013-03-17 18:51:32

+0

這是我發現的唯一可以處理'by ='子句的解決方案:)。從'ddply'驚人的加速。 – user17130 2014-10-22 00:13:19

9

你也可以參照的數據表的副本

sc <- names(x)[2:4] 

sx <- copy(x)[ , (sc) := as.data.table(scale(.SD)), .SDcols = sc] 

規模返回一個矩陣,並IIRC data.table不喜歡矩陣的列分配。

或者,

sx <- copy(x)[ , (sc) := lapply(.SD,scale), .SDcols = sc] 

[中括號(sc)告訴data.table採取從變量的值的LHS值在呼叫範圍,而不是列名sc本身。 ]

+0

+1我最近才發現我們甚至不需要'c()',只需'()'就足夠了。 – 2013-03-17 22:09:22

+1

@MatthewDowle - 我也使用過{}。 – mnel 2013-03-17 22:23:58

+1

整潔。將在某處添加一些關於'()'和'{}'的文檔,然後將其正式化。如果按邏輯列進行子集化,也已經開始在'i'中使用它;例如'DT [(logicalCol)]'。 – 2013-03-17 22:43:13