<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: bglimm autocall macros for postprocessing by group in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/848559#M335480</link>
    <description>&lt;P&gt;Thank you webart999ARM,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I had some trouble running the macro code you provided. But, it was very helpful as a starting point and structure to create my own macro version.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The macro I made below works for me and allows me to use some of the other postprocessing macros. However, it currently does not allow for options within the macros to be changed without manually changing within the macro code. For example, the ALPHA= option within %postint() would need to be changed directly within the macro. I'm sure it could be more efficient, so please feel free to show me more efficient code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm happy to keep the discussion open to hear other ideas.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Bryan&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/* Simulate example posterior results from proc bglimm */
data sims_post;
do simulation = 1 to 10;
	do iteration = 1 to 1000;
		intercept = rand("normal", 4, 1);
		random1_vc_1 = rand("normal", 0.10, 0.02);
		output;
	end;
end;



/* Macro for Bayesian posterior processing with autocall macro.
mac= the name of the autocall macro we want to run (only 1 allowed)
data= name of the dataset that has the posterior data (only 1 allowed)
sim_var= name of the simulation variable (only 1 allowed)
var= name of the parameters within the dataset that &lt;BR /&gt;we want to run the autocall macro on (multiple allowed)*/

%macro post_by_sim(mac=, data=, sim_var=, var=);

  /* Delete previous results table if it exists */
   proc datasets nolist;
		delete &amp;amp;mac._results; 
	run;
	
  /* Identify number of simulations */
  proc sql noprint;
  	select count(distinct &amp;amp;sim_var.) into :nsim
  	from &amp;amp;data.;
  quit;
     
  /*  Loop over each simulation  */
  %do i = 1 %to &amp;amp;nsim.;
  proc sql noprint;
  	create table subset as 
  	select simulation, 
  	%sysfunc(tranwrd(%sysfunc(compbl(&amp;amp;var.)), 
  				%bquote( ), 
  				%bquote(,))) 
  	from &amp;amp;data.
  	where &amp;amp;sim_var. = &amp;amp;i.;
  quit;

 /*  Run selected autocall macro to generate summary stats  */
 %if %lowcase(&amp;amp;mac.) = %bquote(postsum) %then %do; 
  %postsum(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(postint) %then %do; 
  %postint(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(sumint) %then %do; 
  %sumint(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(ess) %then %do; 
  %ess(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(geweke) %then %do; 
  %geweke(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;

  /* Store the summary stats in a table */
 	proc append base = &amp;amp;mac._results
 	data = simresults;
 	run;	
  %end;
  
  proc sort data = &amp;amp;mac._results;
  by parameter;
  run;
  
  proc print data = &amp;amp;mac._results;
  by parameter;
  run;
  
%mend;

/* Use the macro to compute posterior summaries by simulation */
%post_by_sim(mac = postsum,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = postint,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);
	
%post_by_sim(mac = sumint,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = ess,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = geweke,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);&lt;/CODE&gt;&lt;/PRE&gt;</description>
    <pubDate>Thu, 08 Dec 2022 16:41:36 GMT</pubDate>
    <dc:creator>Hopeful</dc:creator>
    <dc:date>2022-12-08T16:41:36Z</dc:date>
    <item>
      <title>bglimm autocall macros for postprocessing by group</title>
      <link>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/847148#M334942</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm running simulations with proc bglimm to estimate coverage, bias, power of hypothesis tests, etc.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My proc bglimm syntax includes a by statement to run the model on each simulated dataset separately.&amp;nbsp;Imagine something like:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;proc bglimm data = sims outpost = sims_post;
by simulation;
class ID;
model y = / dist = normal;
random intercept / subject = ID;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;CODE class=""&gt;&lt;/CODE&gt;I would like to use the autocall macros for postprocessing, such as %postsum(), on the posterior samples:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/v_032/statug/statug_bglimm_details23.htm" target="_blank" rel="noopener"&gt;https://documentation.sas.com/doc/en/pgmsascdc/v_032/statug/statug_bglimm_details23.htm&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;How can I run these postprocessing macros by group (i.e. simulation) and store the results in a table?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Basically, the syntax below with a "by" statement would be great.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;%postsum(data = sims_post, var = intercept)&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Any suggestions?&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 30 Nov 2022 20:47:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/847148#M334942</guid>
      <dc:creator>Hopeful</dc:creator>
      <dc:date>2022-11-30T20:47:23Z</dc:date>
    </item>
    <item>
      <title>Re: bglimm autocall macros for postprocessing by group</title>
      <link>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/848254#M335364</link>
      <description>&lt;P&gt;&lt;SPAN&gt;You can use the &lt;/SPAN&gt;&lt;CODE&gt;%DO&lt;/CODE&gt;&lt;SPAN&gt; loop in SAS to iterate over the different groups defined by the &lt;/SPAN&gt;&lt;CODE&gt;BY&lt;/CODE&gt;&lt;SPAN&gt; statement in your &lt;/SPAN&gt;&lt;CODE&gt;PROC BGLIMM&lt;/CODE&gt;&lt;SPAN&gt; code. For each group, you can call the &lt;/SPAN&gt;&lt;CODE&gt;%postsum&lt;/CODE&gt;&lt;SPAN&gt; macro and store the results in a table. Here's an example of what that might look like:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro postsum_by_group(data=, var=);
  /* Initialize an empty table to store results */
  data results;
  length simulation $32;
  length mean median stderr $32;
  output;

  /* Loop over each group defined by the BY statement */
  %do i = 1 %to &amp;amp;data..n_classes;
    /* Call the %postsum macro for the current group */
    %postsum(data=&amp;amp;data., var=&amp;amp;var., by=simulation, classid=&amp;amp;i.)

    /* Store the results in the table */
    simulation = "Simulation &amp;amp;i";
    mean = mean;
    median = median;
    stderr = stderr;
    output;
  end;
  run;
%mend;

/* Use the macro to compute summaries by group */
%postsum_by_group(data=sims_post, var=intercept);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN&gt;This code defines a &lt;CODE&gt;%postsum_by_group&lt;/CODE&gt; macro that takes in the name of the data set containing the posterior samples and the variable of interest, and computes summaries for each group defined by the &lt;CODE&gt;BY&lt;/CODE&gt; statement. You can then use this macro to compute summaries for the &lt;CODE&gt;intercept&lt;/CODE&gt; variable in your example.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 07 Dec 2022 01:29:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/848254#M335364</guid>
      <dc:creator>webart999ARM</dc:creator>
      <dc:date>2022-12-07T01:29:43Z</dc:date>
    </item>
    <item>
      <title>Re: bglimm autocall macros for postprocessing by group</title>
      <link>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/848559#M335480</link>
      <description>&lt;P&gt;Thank you webart999ARM,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I had some trouble running the macro code you provided. But, it was very helpful as a starting point and structure to create my own macro version.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The macro I made below works for me and allows me to use some of the other postprocessing macros. However, it currently does not allow for options within the macros to be changed without manually changing within the macro code. For example, the ALPHA= option within %postint() would need to be changed directly within the macro. I'm sure it could be more efficient, so please feel free to show me more efficient code.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm happy to keep the discussion open to hear other ideas.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Bryan&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/* Simulate example posterior results from proc bglimm */
data sims_post;
do simulation = 1 to 10;
	do iteration = 1 to 1000;
		intercept = rand("normal", 4, 1);
		random1_vc_1 = rand("normal", 0.10, 0.02);
		output;
	end;
end;



/* Macro for Bayesian posterior processing with autocall macro.
mac= the name of the autocall macro we want to run (only 1 allowed)
data= name of the dataset that has the posterior data (only 1 allowed)
sim_var= name of the simulation variable (only 1 allowed)
var= name of the parameters within the dataset that &lt;BR /&gt;we want to run the autocall macro on (multiple allowed)*/

%macro post_by_sim(mac=, data=, sim_var=, var=);

  /* Delete previous results table if it exists */
   proc datasets nolist;
		delete &amp;amp;mac._results; 
	run;
	
  /* Identify number of simulations */
  proc sql noprint;
  	select count(distinct &amp;amp;sim_var.) into :nsim
  	from &amp;amp;data.;
  quit;
     
  /*  Loop over each simulation  */
  %do i = 1 %to &amp;amp;nsim.;
  proc sql noprint;
  	create table subset as 
  	select simulation, 
  	%sysfunc(tranwrd(%sysfunc(compbl(&amp;amp;var.)), 
  				%bquote( ), 
  				%bquote(,))) 
  	from &amp;amp;data.
  	where &amp;amp;sim_var. = &amp;amp;i.;
  quit;

 /*  Run selected autocall macro to generate summary stats  */
 %if %lowcase(&amp;amp;mac.) = %bquote(postsum) %then %do; 
  %postsum(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(postint) %then %do; 
  %postint(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(sumint) %then %do; 
  %sumint(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(ess) %then %do; 
  %ess(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;
 %else %if %lowcase(&amp;amp;mac.) = %bquote(geweke) %then %do; 
  %geweke(data = subset, var = &amp;amp;var., print = no, 
  out = simresults);
  %end;

  /* Store the summary stats in a table */
 	proc append base = &amp;amp;mac._results
 	data = simresults;
 	run;	
  %end;
  
  proc sort data = &amp;amp;mac._results;
  by parameter;
  run;
  
  proc print data = &amp;amp;mac._results;
  by parameter;
  run;
  
%mend;

/* Use the macro to compute posterior summaries by simulation */
%post_by_sim(mac = postsum,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = postint,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);
	
%post_by_sim(mac = sumint,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = ess,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);

%post_by_sim(mac = geweke,
	data = sims_post, 
	sim_var = simulation, 
	var = intercept random1_vc_1);&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 08 Dec 2022 16:41:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/bglimm-autocall-macros-for-postprocessing-by-group/m-p/848559#M335480</guid>
      <dc:creator>Hopeful</dc:creator>
      <dc:date>2022-12-08T16:41:36Z</dc:date>
    </item>
  </channel>
</rss>

