2015-10-26 21 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