估计 PROC MIXED 中的多重输入
Estimating the multiple input in PROC MIXED
我正在寻找类似于 Proc 分数(来自 proc reg)的东西来估计数据集。
到目前为止我有这样的东西。
PROC MIXED data = maindata noclprint covtest;
Class ID;
Weight w1;
Model TIME = Age Age*Age / Solution cl residual;
Random Intercept Age Age*Age / sub=ID;
Estimate 'ID1' Intercept 1 Age 10 Age*Age 100 | Intercept 1 Age 10 Age*Age 100/ cl Subject 1;
Estimate 'ID2' Intercept 1 Age 12 Age*Age 144 | Intercept 1 Age 12 Age*Age 144/ cl Subject 0 1;
Estimate 'ID3' Intercept 1 Age 11 Age*Age 121 | Intercept 1 Age 11 Age*Age 121/ cl Subject 0 0 1;
Estimate 'ID4' Intercept 1 Age 15 Age*Age 225 | Intercept 1 Age 15 Age*Age 225/ cl Subject 0 0 0 1;
(. . . You get the point)
run; quit;
这是我的估计数据集:
ID Age AgeSq
1 10 100
2 12 144
3 11 121
4 15 225
...
50 9 81
我的问题是,还有比 50 个这样的估算语句更有效的方法吗?
我试过 PROC PLM。 PROC PLM (SCORE(PREDICTED)) 的问题在于它没有考虑随机效应。(http://support.sas.com/documentation/cdl/en/statug/63347/HTML/default/viewer.htm#statug_plm_a0000000126.htm)
编辑:我没有正确阅读你关于 plm
的问题的结尾。抱歉,请参阅下面的中断以获取替代方案。
这不是我做过的事情,但我相信您可以使用 proc plm
实现您想要的,它可以使用 proc mixed
、[=17] 生成的模型对数据集(除其他外)进行评分=] 和其他人。
基本方法是使用 store
statement:
存储模型的二进制表示
proc mixed;
...
store sasuser.myModel;
run;
然后使用 proc plm
:
处理您的新数据
proc plm source = sasuser.mixed;
...
score data = inData out = want;
run;
user guide should help with the finer points.
Rick Wicklin here.
对类似问题进行了更多讨论
作为一种快速而肮脏的替代方法,您可以使用宏变量来编写您的估计 statements
:
proc sql;
select
"estimate 'ID" || put(ID, best.) || "' intercept 1 Age " ||
put(Age, best.) || " Age*Age " || put(Age**2, best.) ||
" | intercept 1 Age " || put(Age, best.) || " Age*Age " ||
put(Age**2, best.) || " / cl subject" || repeat(" 0", (ID - 1)) || "1;"
into :estList separated by " "
from inEst
order by ID;
quit;
proc mixed data = maindata noclprint covtest;
class id;
weight w1;
model time = age age*age / solution cl residual;
random intercept age age*age / sub = id;
&estList.;
ods output estimates = want;
quit;
基本上,您将所有 estimate
语句创建为 sql 查询中的字符串,并将它们存储在宏变量中。这种方法有其缺点:
- 代码变得模糊;不清楚正在做什么。我会对这样的代码进行大量注释,以使任何可怜的维护者都清楚地知道您为什么这样做以及它在做什么。
- 宏变量的长度有限(65534 个字符)。如果您的变量有超过此值的任何风险,您应该将其拆分(使用
call symput
和 do
循环)并从 %do
循环中调用这些行。
编辑:您可能想要探索的另一种选择。
在最近的版本中,proc mixed
和 proc plm
支持 code
statement which can be used 输出对新观察进行评分所需的 SAS 数据步骤代码。如有必要,您可以使用生成的代码作为基础,并根据您希望执行的分析对其进行修改。
call symput
骨架:
data _NULL_;
set inEst nobs = obs;
length mVar .;
/* Store number of lines in a macro variable */
if _N_ = 1 then call symput("nVars", obs);
mVar = "est_" || put(_N_, best.);
value = *** Code to make estimate statement ***;
/* Create a new macro variable for each line */
call symput(mVar, value);
run;
%macro temp;
*** Code ***;
%do i = 1 %to &nVars.;
&&est_&i.
%end;
*** Code ***;
%mend temp;
%temp;
"Macro variables have have a finite length (65534 characters). If there is any risk of your variable exceeding this you should split it up (with call symput and a do loop) and call the lines from a %do loop."
另一种选择是将估计列表设置为单独的代码文件并使用 %include 这对于不需要参数的大量变量列表或重复代码块也很有用。
我正在寻找类似于 Proc 分数(来自 proc reg)的东西来估计数据集。
到目前为止我有这样的东西。
PROC MIXED data = maindata noclprint covtest;
Class ID;
Weight w1;
Model TIME = Age Age*Age / Solution cl residual;
Random Intercept Age Age*Age / sub=ID;
Estimate 'ID1' Intercept 1 Age 10 Age*Age 100 | Intercept 1 Age 10 Age*Age 100/ cl Subject 1;
Estimate 'ID2' Intercept 1 Age 12 Age*Age 144 | Intercept 1 Age 12 Age*Age 144/ cl Subject 0 1;
Estimate 'ID3' Intercept 1 Age 11 Age*Age 121 | Intercept 1 Age 11 Age*Age 121/ cl Subject 0 0 1;
Estimate 'ID4' Intercept 1 Age 15 Age*Age 225 | Intercept 1 Age 15 Age*Age 225/ cl Subject 0 0 0 1;
(. . . You get the point)
run; quit;
这是我的估计数据集:
ID Age AgeSq
1 10 100
2 12 144
3 11 121
4 15 225
...
50 9 81
我的问题是,还有比 50 个这样的估算语句更有效的方法吗?
我试过 PROC PLM。 PROC PLM (SCORE(PREDICTED)) 的问题在于它没有考虑随机效应。(http://support.sas.com/documentation/cdl/en/statug/63347/HTML/default/viewer.htm#statug_plm_a0000000126.htm)
编辑:我没有正确阅读你关于 plm
的问题的结尾。抱歉,请参阅下面的中断以获取替代方案。
这不是我做过的事情,但我相信您可以使用 proc plm
实现您想要的,它可以使用 proc mixed
、[=17] 生成的模型对数据集(除其他外)进行评分=] 和其他人。
基本方法是使用 store
statement:
proc mixed;
...
store sasuser.myModel;
run;
然后使用 proc plm
:
proc plm source = sasuser.mixed;
...
score data = inData out = want;
run;
user guide should help with the finer points.
Rick Wicklin here.
对类似问题进行了更多讨论作为一种快速而肮脏的替代方法,您可以使用宏变量来编写您的估计 statements
:
proc sql;
select
"estimate 'ID" || put(ID, best.) || "' intercept 1 Age " ||
put(Age, best.) || " Age*Age " || put(Age**2, best.) ||
" | intercept 1 Age " || put(Age, best.) || " Age*Age " ||
put(Age**2, best.) || " / cl subject" || repeat(" 0", (ID - 1)) || "1;"
into :estList separated by " "
from inEst
order by ID;
quit;
proc mixed data = maindata noclprint covtest;
class id;
weight w1;
model time = age age*age / solution cl residual;
random intercept age age*age / sub = id;
&estList.;
ods output estimates = want;
quit;
基本上,您将所有 estimate
语句创建为 sql 查询中的字符串,并将它们存储在宏变量中。这种方法有其缺点:
- 代码变得模糊;不清楚正在做什么。我会对这样的代码进行大量注释,以使任何可怜的维护者都清楚地知道您为什么这样做以及它在做什么。
- 宏变量的长度有限(65534 个字符)。如果您的变量有超过此值的任何风险,您应该将其拆分(使用
call symput
和do
循环)并从%do
循环中调用这些行。
编辑:您可能想要探索的另一种选择。
在最近的版本中,proc mixed
和 proc plm
支持 code
statement which can be used 输出对新观察进行评分所需的 SAS 数据步骤代码。如有必要,您可以使用生成的代码作为基础,并根据您希望执行的分析对其进行修改。
call symput
骨架:
data _NULL_;
set inEst nobs = obs;
length mVar .;
/* Store number of lines in a macro variable */
if _N_ = 1 then call symput("nVars", obs);
mVar = "est_" || put(_N_, best.);
value = *** Code to make estimate statement ***;
/* Create a new macro variable for each line */
call symput(mVar, value);
run;
%macro temp;
*** Code ***;
%do i = 1 %to &nVars.;
&&est_&i.
%end;
*** Code ***;
%mend temp;
%temp;
"Macro variables have have a finite length (65534 characters). If there is any risk of your variable exceeding this you should split it up (with call symput and a do loop) and call the lines from a %do loop."
另一种选择是将估计列表设置为单独的代码文件并使用 %include 这对于不需要参数的大量变量列表或重复代码块也很有用。