Ok we are getting somewhere. For anyone interested code is below. I only had to make some slight changes which I think made the models the same:
dm=pm.Deterministic("dm",d[trt]-d[trt[:,0:1]])
This effectively vectorizes the loop that they were doing, Other parts vectorize automatically by broadcasting so no change was necessary. The posteriors that I now get are well defined for every study since they get all used
And how do you want to generalize this?
import arviz as az
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import pymc as pm
import pytensor.tensor as pt
import pytensor
data=pd.read_csv("data.csv")
trials=data[["n1","n2"]]
events=data[["r1","r2"]]
trt=data[["t1","t2"]].to_numpy()-1
N=len(trials)
studies=data["study"]
treatments=["SK","t-PA","at-PA","SK+t-PA","r-PA","TNK","PTCA"]
coords = {"studies": studies, "treatments":treatments}
reference=np.array([0,1,1,1,1,1,1])
with pm.Model(coords=coords) as femodel:
r=pm.MutableData('r',events)
n=pm.MutableData('n',trials)
d_=pm.Normal("d_",mu=0,sigma=100,dims="treatments")
d=pm.Deterministic("d",d_*reference,dims="treatments")
mu=pm.Normal("mu",mu=0,sigma=100,dims="studies",shape=(N,1))
dm=pm.Deterministic("dm",d[trt]-d[trt[:,0:1]])
linpred=pm.Deterministic("linpred",mu+dm)
p=pm.Deterministic("p",pm.invlogit(linpred))
y=pm.Binomial("y",n=n,p=p,observed=r)
fedata=pm.sample(1000,tune=500)
az.plot_posterior(fedata)
data.csv (1.6 KB)
