2015-10-26 25 views
2

创建一组(可能很多)后验分布基本问题是:如何使用现有data.table的一列中的值作为列名创建新的空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 

不过,我可能有很多人,我希望自动列X的DT转换成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

什么是你在循环中使用的功能? –

+0

@Colonel Beauvel感谢您的回答,它帮助我产生了一些可行的方法(尽管毫无疑问仍然可以改进语法),我已经详细解答了这个问题。我不知道约定是什么,但我不想给出函数的具体细节。这是一个多步骤的过程,最初涉及一个更大的(长形式)data.table,每个人有许多行(每个人只有一个参数被估计,但是它是基于大量变量的值)。 – RichardB

回答

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