# How to achieve fractional polynomials in stan

Hi, I’m wondering if fractional polynomials could be achieved in stan.
Following the definition of Patrick Royston et al. (1994), for example, a fractional polynomial of degree 2 can be illustrated as

\phi_2(x;\xi,p)=\xi_0+\xi_1 x^{(p_1)}+\xi_2 x^{(p_2)},

where x>0, \xi=(\xi_0,\xi_1,\xi_2) is coefficient, p=(p_1,p_2) is the vector of power. These p_j come from a set S={-2,-1,-0.5,0,0.5,1,2,3}. If p_j=0, then x^{(p_j)}=lnx; If p_1=p_2, then x^{p_2}=x^{p_1}lnx.
Maybe doing variable selection by backward elimination is one option, but I don’t know how to achieve it. Any advice would be appreciated.

Sorry for not answering earlier.

One thing I am not clear about is what quantities are known and what are parameters to be estimated. If everything is a parameter, then it still should be theoretically possible by marginalizing out the discrete parameters in p with something like (just a sketch, code not tested) - also I am ignoring the special cases and just taking x^{(p_k)} = x^{p_k} (but the special cases should be straightforward to add

EDIT: The following is in fact likely not correct code, sorry for any confusion.

data {
int<lower=1> S_size;
vector[S_size] S;
int N;
vector[N] x;
vector[N] y;
}

parameters {
simplex[S_size * S_size] p_probs; //The probability that p = (p_1,p_2) for all pairs of p_1, p_2
vector ksi[S_size * S_size]; //Separate parameters need to be maintained for each possible polynomial
real<lower=0> sigma;
}

model {
vector[S_size * S_size] partial_lp;
for(i1 in 1:S_size) {
for(i2 in 1:S_size) {
int index = (i1 - 1) * S_size + i2;
real p1 = S[i1];
real p2 = S[i2];
vector[N] mu;

//Compute the likelihood assuming specific values for p1, p2
for(n in 1:N) {
mu[n] = ksi[index, 1] + ksi[index, 2] * x[n] ^ p1 + ksi[index, 3] * x[n] ^ p2;
}

partial_lp[index] = normal_lpdf(y | mu, sigma);
}
}

//Weigh all the partial probabilities by their estimated probability
target += log_sum_exp(log(p_probs) + partial_lp);

}



I however fear this will be quite costly and that the model might not be well identified without a lot of data.

Best of luck with your model!

Hi, martin, thank you so much. (To be honest I did not expect any reply)
Your code provided a nice example for constructing fractional polynomials.
And as you concerned, I did find that the fracpoly is not a good or efficient choice. With my dataset, simple quadratic or cubic formations could do the same job, with less computation time. I think I will go with simple model. But again, thanks for the example code.

1 Like