基本问题是:如何使用现有data.table的一列中的值作为列名创建一个新的空data.table?所以从这个:
set.seed(1)
DT = data.table(x=c("a","b","c","d","e","f"), y=runif(6),key="x")
> DT
x y
1: a 0.2655087
2: b 0.3721239
3: c 0.5728534
4: d 0.9082078
5: e 0.2016819
6: f 0.8983897
我想自动创建一个看起来像这样的data.table(带有数字列):
> POST
Empty data.table (0 rows) of 6 cols: a,b,c,d,e,f
将问题放在标题的上下文中:DT [,x]中的字符代表个体; DT [,y]中的值是当前迭代的后验参数估计。我以这种方式组织它,因为它似乎是快速和直接的每行运行计算(计算可能性,接受/拒绝更新的值等)。
但是,我想将y中的值存储为另一个表中的新行(个体(x)作为列,一行中每次迭代的值(y))。这有助于下游,例如使其直接创建一个mcmc对象。
主要问题是我不知道如何自动创建一个空data.table来保存后验分布,DT [,x]中的值作为列名。我想在第一次迭代之前看起来像这样:
POST<-data.table(a=numeric(0),b=numeric(0),c=numeric(0),
d=numeric(0),e=numeric(0),f=numeric(0))
> POST
Empty data.table (0 rows) of 6 cols: a,b,c,d,e,f
但我可能有很多人,我想自动将DT中的列x转换为POST的列名。有什么建议吗?
要在每次迭代时将DT [,y]的新值附加到POST,这似乎有效:
setkey(DT,x)
POST<-rbind(POST,data.table(t(DT[,.(y)])),use.names=FALSE)
总而言之,整个事情应该是这样的:
#Table used for calculations, with initial values#
set.seed(1)
DT = data.table(x=c("a","b","c","d","e","f"), y=runif(6),key="x")
#Table for storing posterior (*automate*)#
POST<-data.table(a=numeric(0),b=numeric(0),c=numeric(0),
d=numeric(0),e=numeric(0),f=numeric(0))
#for loop
#Modify values of y, then:
setkey(DT,x)
POST<-rbind(POST,data.table(t(DT[,.(y)])),use.names=FALSE)
编辑:基于Beauvel上校的回复,我现在有了这个,它产生了我想要的东西,但我还没想出如何在每次迭代时粘贴新列表元素的名称:
#Create a list outside the loop
POST<- list()
#For loop
#First iteration:
POST$1<-data.table(t(DT[,y]));setattr(
POST$1, 'names', DT[,x])
#Second iteration:
POST$2<-data.table(t(DT[,y]));setattr(
POST$2, 'names', DT[,x])
#End of loop
> rbindlist(POST, use.names=TRUE)
a b c d e f
1: 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819 0.8983897
2: 0.2655087 0.3721239 0.5728534 0.9082078 0.2016819 0.8983897
(忽略每行中的数字相同 - 这就是我想做的事。)
答案 0 :(得分:1)
目标是在贝叶斯分析的每次迭代中在后验分布中存储一组接受的参数值,并因此创建包含潜在大量独立参数的完整后验分布的对象。为了提高效率,可以按行进行可能性计算和接受/拒绝(有几个步骤,此处未指定),然后将结果存储在列中:
#x contains individual reference numbers, y contains the parameter estimate.
#Initial values:
set.seed(1)
DT = data.table(x=c("a","b","c","d","e","f"), y=runif(6),key="x")
> DT
x y
1: a 0.7581031
2: b 0.7244989
3: c 0.9437248
4: d 0.5476466
5: e 0.7117439
6: f 0.3889051
#Create a list object to store the posterior
POST<-list()
#For loop
for(k in 1:10){
#After various calculations, DT has a new set of accepted posterior values.
#Just as a fake example:
DT[,y:=runif(6)]
#Add these to POST.
setkey(DT,x)
POST[[k]]<-data.table(t(DT[,y]));setattr(POST[[k]], 'names', DT[,x])
}#End of loop
#Create a mcmc object from the set of posterior distributions.
require(coda)
POST<-mcmc(rbindlist(POST, use.names=TRUE))
> POST
Markov Chain Monte Carlo (MCMC) output:
Start = 1
End = 10
Thinning interval = 1
a b c d e f
[1,] 0.51116978 0.20754511 0.2286581 0.5957120 0.57487220 0.07706438
[2,] 0.03554058 0.64279549 0.9286152 0.5980924 0.56090075 0.52602772
[3,] 0.98509522 0.50764182 0.6827881 0.6015412 0.23886868 0.25816593
[4,] 0.72930962 0.45257083 0.1751268 0.7466983 0.10498764 0.86454495
[5,] 0.61464497 0.55715954 0.3287773 0.4531314 0.50044097 0.18086636
[6,] 0.52963060 0.07527575 0.2777559 0.2126995 0.28479048 0.89509410
[7,] 0.44623532 0.77998489 0.8806190 0.4131242 0.06380848 0.33548749
[8,] 0.72372595 0.33761533 0.6304141 0.8406146 0.85613166 0.39135928
[9,] 0.38049389 0.89544543 0.6443158 0.7410786 0.60530345 0.90308161
[10,] 0.29373016 0.19126011 0.8864509 0.5033395 0.87705754 0.18919362