我想在data.table中创建一个变量,因为语法更具可读性,但是然后将其存储在矩阵中以便更快地访问。
我想出了一个笨拙的方法(参见下面的函数dt_to_mat
),我希望有一个更好的选择(不承担另一个包裹或奇怪属性的包袱)。 “更好”,我的意思是易于维护和扩展,以便从几个data.table'margin'列(两个矩阵)和一个'value'列中创建一个数组。
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
重塑命令中最不可靠的。即使不剥离其属性,它也会通过is.matrix()
测试,但需要构建公式。
答案 0 :(得分: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)