2017-01-27 8 views
3

Я хотел бы, чтобы масштабировать выбор переменных в data.table по группе «сессия»:масштаба группы в data.table

session  score1 score2 
1:  1 0.11111111 0.6000000 
2:  1 0.00000000 0.5333333 
3:  1 0.27777778 0.6666667 
4:  1 0.66666667 0.8666667 
5:  1 0.83333333 1.0000000 
6:  2 0.07692308 0.5757576 
7:  2 0.25641026 0.6363636 
8:  2 0.00000000 0.5303030 
9:  2 0.64102564 0.7878788 
10:  2 0.84615385 1.0000000 

Я пробовал:

dt[,(2:3):=lapply(.SD,scale),by="session",.SDcols=2:3] 

Но я получите ошибку:

Error in `[.data.table`(dt, , `:=`((2:3), lapply(.SD, scale)), by = "session", : 
All items in j=list(...) should be atomic vectors or lists. If you are trying something like j=list(.SD,newcol=mean(colA)) then use := by group instead (much quicker), or cbind or merge afterwards. 

Код работает, но только без переменной группировки (сеанса). Что я делаю не так?

ответ

4

Выходная функция scale является matrix, поэтому конвертировать его в vector

dt[, c("score1", "score2") := lapply(.SD, function(x) as.vector(scale(x))), by = session] 
dt 
# session  score1  score2 
# 1:  1 -0.7433155 -0.6859943 
# 2:  1 -1.0530303 -1.0289917 
# 3:  1 -0.2787433 -0.3429970 
# 4:  1 0.8052585 0.6859944 
# 5:  1 1.2698307 1.3719886 
# 6:  2 -0.7847341 -0.6824535 
# 7:  2 -0.2942753 -0.3650335 
# 8:  2 -0.9949307 -0.9205191 
# 9:  2 0.7567078 0.4285175 
#10:  2 1.3172322 1.5394886 

Чтобы лучше понять его, попробовать его на простом векторе

scale(1:10) 
#  [,1] 
# [1,] -1.4863011 
# [2,] -1.1560120 
# [3,] -0.8257228 
# [4,] -0.4954337 
# [5,] -0.1651446 
# [6,] 0.1651446 
# [7,] 0.4954337 
# [8,] 0.8257228 
# [9,] 1.1560120 
#[10,] 1.4863011