Usando um vetor gerado em SAS/IML como variável macro
Pergunta
Estou escrevendo uma macro que executará PROC MIXED com a variação residual de nível 1 fixada em um valor próximo de zero usando a instrução PARMS.Estou tentando gerar a maior parte dos valores iniciais para a instrução PARMS usando SAS/IML, algo como:
%macro test (dataset= , classroom= , preds= , outcome=);
proc iml;
/*count number of variables*/
%let nvars = 0;
%do %while(%qscan(&preds,&nvars+1,%str( )) ne %str());
%let nvars = %eval(&nvars+1);
%end;
/*determine location of level-1 residual in the start value vector*/
%let error_location = %eval(((&nvars*(&nvars-1))/2)+&nvars+1);
/*create vector of start values from lower triangle of identity matrix*/
start_vector = symsqr(I(&nvars));
%let starts = %str(start_vector[label=""]);
/*analyze data*/
proc mixed data=&dataset noprofile method=ml;
class &classroom;
model &outcome = &preds /noint;
random &preds /type=un sub=&classroom g;
parms
&starts
.00000001 /hold= &error_location;
run;
quit;
%mend;
O código funciona bem sem a instrução PARMS no código PROC MIXED.No entanto, quando executo o código como está, o SAS aparentemente coloca a string literal 'start_vector[label=""]' após PARMS em vez de listar os valores gerados pelo IML.
Como posso evitar esse erro e fazer com que o SAS especifique os valores contidos em START_VECTOR como valores iniciais para a instrução PARMS?
Solução
Você deve usar o SYMPUT
ou SYMPUTX
rotinas em SAS/IML para converter um vetor em uma variável macro.
Esta é uma maneira de colocar um vetor em uma única string em uma variável macro.
proc iml;
start = {"Hi","Bye"};
call symput("start",rowcat(start`));
%put &start;
quit;
Com um vetor numérico, você precisa usar char
para convertê-lo:
proc iml;vetor_inicial = j(5);chame symputx("start_vector",rowcat(char(j)));%colocar &start_vector;desistir;
Com uma matriz numérica, você precisa usar SHAPE
para achatá-lo:
proc iml;
start_vector = j(5,5);
call symputx("start_vector",rowcat(shape(char(start_vector),1)));
%put &start_vector;
quit;
Outras dicas
Seu problema e duas soluções são discutidos no artigo "Passando valores do PROC IML para procedimentos SAS."
Você tem que agrupar isso em uma macro?Nesse caso, as instruções SUBMIT e ENDSUBMIT não funcionarão, pois não podem ser chamadas de uma macro.No entanto, como o SAS/IML permite definir e chamar módulos com argumentos, geralmente evito a linguagem macro e defino um módulo que recebe argumentos e, em seguida, chamo o módulo diretamente.