2015-10-26 3 views
2

Основной вопрос: как создать новую пустую таблицу данных, используя значения в одном столбце существующей таблицы данных в качестве имен столбцов ? Так что с этого:Создание набора (возможно, многих) задних распределений итерационно с использованием 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 в имена столбцов для POST. Какие-либо предложения?

Для добавления новых значений DT [, у], чтобы 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) 

EDIT: на основании ответа полковника Бовела у меня теперь есть это, которое производит то, что я хочу, но я еще не понял, как вставить имя для нового элемента списка на каждой итерации:

#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