Estou tentando executar uma regressão inflada a zero para uma variável de resposta contínua em R. Estou ciente de uma implementação gamlss, mas eu realmente gostaria de experimentar esse algoritmo de Dale McLerran, que é conceitualmente um pouco mais direto. Infelizmente, o código está no SAS e não sei como reescrevê-lo para algo como nlme.
O código é o seguinte:
proc nlmixed data=mydata;
parms b0_f=0 b1_f=0
b0_h=0 b1_h=0
log_theta=0;
eta_f = b0_f + b1_f*x1 ;
p_yEQ0 = 1 / (1 + exp(-eta_f));
eta_h = b0_h + b1_h*x1;
mu = exp(eta_h);
theta = exp(log_theta);
r = mu/theta;
if y=0 then
ll = log(p_yEQ0);
else
ll = log(1 - p_yEQ0)
- lgamma(theta) + (theta-1)*log(y) - theta*log(r) - y/r;
model y ~ general(ll);
predict (1 - p_yEQ0)*mu out=expect_zig;
predict r out=shape;
estimate "scale" theta;
run;
De: http://listserv.uga.edu/cgi-bin/wa?A2=ind0805A&L=sas-l&P=R20779
ADICIONAR:
Nota: Não há efeitos mistos presentes aqui - apenas corrigidos.
A vantagem desse ajuste é que (embora os coeficientes sejam os mesmos que se você ajustasse separadamente uma regressão logística para P (y = 0) e uma regressão de erro gama com link de log para E (y | y> 0)), você pode estimar a função combinada E (y) que inclui os zeros. Pode-se prever esse valor no SAS (com um CI) utilizando a linha predict (1 - p_yEQ0)*mu
.
Além disso, é possível escrever declarações de contraste personalizadas para testar a significância das variáveis preditoras em E (y). Por exemplo, aqui está outra versão do código SAS que usei:
proc nlmixed data=TestZIG;
parms b0_f=0 b1_f=0 b2_f=0 b3_f=0
b0_h=0 b1_h=0 b2_h=0 b3_h=0
log_theta=0;
if gifts = 1 then x1=1; else x1 =0;
if gifts = 2 then x2=1; else x2 =0;
if gifts = 3 then x3=1; else x3 =0;
eta_f = b0_f + b1_f*x1 + b2_f*x2 + b3_f*x3;
p_yEQ0 = 1 / (1 + exp(-eta_f));
eta_h = b0_h + b1_h*x1 + b2_h*x2 + b3_h*x3;
mu = exp(eta_h);
theta = exp(log_theta);
r = mu/theta;
if amount=0 then
ll = log(p_yEQ0);
else
ll = log(1 - p_yEQ0)
- lgamma(theta) + (theta-1)*log(amount) - theta*log(r) - amount/r;
model amount ~ general(ll);
predict (1 - p_yEQ0)*mu out=expect_zig;
estimate "scale" theta;
run;
Então, para estimar "presente1" versus "presente2" (b1 versus b2), podemos escrever esta declaração de estimativa:
estimate "gift1 versus gift 2"
(1-(1 / (1 + exp(-b0_f -b1_f))))*(exp(b0_h + b1_h)) - (1-(1 / (1 + exp(-b0_f -b2_f))))*(exp(b0_h + b2_h)) ;
R pode fazer isso?
Respostas:
Tendo passado algum tempo nesse código, parece-me que basicamente:
1) Faz uma regressão logística com o lado direito
b0_f + b1_f*x1
ey > 0
como variável alvo,2) Para as observações para as quais y> 0, executa uma regressão com o lado direito
b0_h + b1_h*x1
, uma probabilidade Gamma elink=log
,3) Também estima o parâmetro de forma da distribuição gama.
Maximiza a probabilidade em conjunto, o que é bom, porque você só precisa fazer uma chamada de função. No entanto, a probabilidade se separa de qualquer maneira, para que você não obtenha melhores estimativas de parâmetros.
Aqui está um código R que faz uso da
glm
função para economizar esforços de programação. Pode não ser o que você gostaria, pois obscurece o próprio algoritmo. O código certamente também não é tão limpo quanto deveria / deveria ser.O parâmetro de forma para a distribuição Gamma é igual a 1 / o parâmetro de dispersão para a família Gamma. Coeficientes e outras coisas que você deseja acessar programaticamente podem ser acessados nos elementos individuais da lista de valores de retorno:
A previsão pode ser feita usando a saída da rotina. Aqui está mais um código R que mostra como gerar valores esperados e outras informações:
E uma amostra:
Agora, para a extração por coeficiente e os contrastes:
fonte
foo.pred$fit
fornece a estimativa pontual de E (y), mas o componentefoo.pred$pred.ygt0$pred
fornece E (y | y> 0). Eu adicionei no cálculo de erro padrão para y, BTW, retornado como se.fit. Os coeficientes podem ser obtidos dos componentes por coeficientes (foo.pred$pred.ygt0
) e coeficientes (foo.pred$pred.p.ygt0
); Escreverei uma rotina de extração e uma rotina de contraste daqui a pouco.