2013-08-16 2 views
0

Я хочу создать переменную в таблице data.table, потому что синтаксис более читабельен, но затем сохраните его в матрице для более быстрого доступа.из таблицы с тремя столбцами. В таблицу

Я придумал неуклюжий способ сделать это (см. Функцию dt_to_mat ниже), и я надеюсь, что есть лучшая альтернатива (которая не несет багаж другой упаковки или странные атрибуты). «Лучше», я имею в виду простоту поддержки и расширение для создания массива из нескольких столбцов data.table «margin» (два для матрицы) и одного столбца «значение».

get_w <- function(D,y){ 
    (1+c_wD*D)*(c_w0+c_w1*y)} 
c_w0 = 1; c_w1 = 1; c_wD = .1 
Tbar = 10L 

wdt  <- CJ(D=0:1,y=0:Tbar)[,w:=get_w(D,y)] 
#  D y w 
# 1: 0 0 1.0 
# 2: 0 1 2.0 
# 3: 0 2 3.0 
# 4: 0 3 4.0 
# 5: 0 4 5.0 
# 6: 0 5 6.0 
# 7: 1 0 1.1 
# 8: 1 1 2.2 
# 9: 1 2 3.3 
# 10: 1 3 4.4 
# 11: 1 4 5.5 
# 12: 1 5 6.6 

... А потом хранить это это матрица:

dt_to_mat <- function(DT){ 
    fla <- paste0(c(names(DT),'~','+')[c(3,4,1,5,2)],collapse="") 
    out <- xtabs(fla,DT) 
    attr(out,'call') <- NULL 
    attr(out,'class')<- NULL 
    out 
} 

wmat <- dt_to_mat(wdt) 
# y 
# D  0 1 2 3 4 5 
# 0 1.0 2.0 3.0 4.0 5.0 6.0 
# 1 1.1 2.2 3.3 4.4 5.5 6.6 

xtabs (который я использую здесь), казалось, как наименее страшное из base RESHAPE команд. Он проходит тест is.matrix(), даже не снимая его атрибутов, но требует построения формулы.

ответ

2

Попробуйте это:

as.matrix(wdt[, setNames(as.list(w), y), by = D][, D := NULL]) 
#  0 1 2 3 4 5 
#[1,] 1.0 2.0 3.0 4.0 5.0 6.0 
#[2,] 1.1 2.2 3.3 4.4 5.5 6.6 

Согласно комментариям, это, вероятно, лучше использовать acast из reshape2 для этого:

library(reshape2) 
acast(wdt, D ~ y) 

# or for the multidimensional case 
wdt2 <- CJ(D1=1:2,D2=1:2,y=1:3)[,w:=D1/D2*log(y)] 
acast(wdt2, D1 ~ D2 ~ y) 
+0

Спасибо. В моем желаемом выходе значения D - это метки строк, а не их собственный столбец. Кроме того, любая идея, как распространить это на data.table, начиная с> 2 «полей» (например, поворот 'wdt2 <- CJ (D1 = 1: 2, D2 = 1: 2, y = 1: 3) [, w: = D1/D2 * log (y)] 'в массив значений для' w')? – Frank

+0

@Frank отредактирован, чтобы вытащить 'D', не уверен в многомерных массивах – eddi

+0

Ладно, спасибо. Еще одна приятная вещь была бы, если бы мне не нужно было знать имена столбцов раньше времени (просто автоматически беря последний столбец как значение для значений, а остальные - как поля). Я думаю, что, может быть, мне придется укусить пулю и научиться использовать «acast», у которого есть аргумент «margin» (как было предложено в отложенном ответе). – Frank

Смежные вопросы