```Date: Fri, 16 Apr 2004 06:27:20 -0400 Reply-To: bramley.michaelp@KENDLE.COM Sender: "SAS(r) Discussion" From: Michael Bramley Subject: GENMOD, GEE,CLASS statments and the order of the variables therein Content-Type: text/plain; charset="us-ascii" Dale: Did I miss something? If the model is E[Y] = A + B + A*B, where A has 2 levels and B has 3 levels, then should not the estimates of the difference between A1 and A2 @ each of the levels of B include A1 and A2, since E[Y|A=A1,B=Bi] - E[Y|A=A2,B=Bi] = A1 + Bi + A1*Bi - A2 - Bi - A2*Bi = A1 - A2 - (A1 - A2) * Bi, for all i ? Sincerely, Michael Bramley ------------------------------ Date: Thu, 15 Apr 2004 17:22:43 -0700 From: Dale McLerran Subject: Re: GENMOD, GEE,CLASS statments and the order of the variables therein Winston has pointed us in the general direction. Actually the section on "Parameterization of PROC GLM models" is in the Details section of the GLM procedure. We find there a section about crossed effects which states: First, PROC GLM reorders the terms to correspond to the order of the variables in the CLASS statement; thus, B*A becomes A*B if A precedes B in the CLASS statement. Then, PROC GLM generates columns for all combinations of levels that occur in the data. The order of the columns is such that the rightmost variables in the cross index faster than the leftmost variables. No columns are generated corresponding to combinations of levels that do not occur in the data. These same rules hold throughout SAS/STAT whenever a procedure allows crossing of variables named on a class statement. Now, suppose that we have class variables A with 2 levels and B with 3 levels. Suppose further that we name variable A first on a class statement. Now, let's construct the following estimates: 1) difference between a1 and a2 at each of the three levels of B, and 2) difference between b1 and b2, b1 and b3, and b2 and b3 at each of the two levels of A. Following the rules about crossed effects, we would have the following estimate statements: a1 a1 a1 a2 a2 a2 b1 b2 b3 b1 b2 b3 estimate "a1-a2 @ b1" a*b 1 0 0 -1 0 0; estimate "a1-a2 @ b2" a*b 0 1 0 0 -1 0; estimate "a1-a2 @ b3" a*b 0 0 1 0 0 -1; estimate "b1-b2 @ a1" a*b 1 -1 0 0 0 0; estimate "b1-b3 @ a1" a*b 1 0 -1 0 0 0; estimate "b2-b3 @ a1" a*b 0 1 -1 0 0 0; estimate "b1-b2 @ a2" a*b 0 0 0 1 -1 0; estimate "b1-b3 @ a2" a*b 0 0 0 1 0 -1; estimate "b2-b3 @ a2" a*b 0 0 0 0 1 -1; Now, if we changed the class statement so that the variable B was listed before the variable A, then the appropriate estimate statements would be b1 b1 b2 b2 b3 b3 a1 a2 a1 a2 a1 a2 estimate "a1-a2 @ b1" a*b 1 -1 0 0 0 0; estimate "a1-a2 @ b2" a*b 0 0 1 -1 0 0; estimate "a1-a2 @ b3" a*b 0 0 0 0 1 -1; estimate "b1-b2 @ a1" a*b 1 0 -1 0 0 0; estimate "b1-b3 @ a1" a*b 1 0 0 0 -1 0; estimate "b2-b3 @ a1" a*b 0 0 1 0 -1 0; estimate "b1-b2 @ a2" a*b 0 1 0 -1 0 0; estimate "b1-b3 @ a2" a*b 0 1 0 0 0 -1; estimate "b2-b3 @ a2" a*b 0 0 0 1 0 -1; Note that if we changed the order of the variables on the class statement but did not change the specification of the effects in the estimate statement, we would end up with b1 b1 b2 b2 b3 b3 a1 a2 a1 a2 a1 a2 estimate "a1@b1-a2@b2" a*b 1 0 0 -1 0 0; estimate "b1@a2-b3@a1" a*b 0 1 0 0 -1 0; estimate "b2@a1-b3@a2" a*b 0 0 1 0 0 -1; estimate "a1-a2 @ b1 " a*b 1 -1 0 0 0 0; estimate "b1-b2 @ a1 " a*b 1 0 -1 0 0 0; estimate "b1@a2-b2@a1" a*b 0 1 -1 0 0 0; estimate "b2@a2-b3@a1" a*b 0 0 0 1 -1 0; estimate "b2-b3 @ a2 " a*b 0 0 0 1 0 -1; estimate "a1-a2 @ b3 " a*b 0 0 0 0 1 -1; Some of these may well be inestimable. For information about estimability, see the SAS/STAT documentation, section "The Four Types of Estimable Functions", subsection "Estimability", sub-subsection "General Form of an Estimable Function". Dale --- Winston Groenewald <922424942@UKZN.AC.ZA> wrote: > James, > > GENMOD and GLM use the same rules for constructing the design matrix. > As such, you should be able to glean much information from the > "Parameterisation of PROC GLM models" section in the OnLineDoc of the > CLASS statement of GLM. > > Regards, > > Winston Groenewald > Forestry Dept. - Science and Agriculture > Bag X01 > University of KwaZulu-Natal > Scottsville > 3209 Pietermaritzburg > 27-11-260-6098 (W) > 27-11-260-6005 (F) > > == Rugby is for men too scared to skydive!! == > > >>> James Algina 04/15/04 11:29PM >>> > I could not find verification of Paul's point in the help file for > the > class statement in genmod. Can someone tell me where this feature of > the > genmod class statement is explained? > > > > Paul R Swank wrote: > > >The order in the class statement does matter for contrasts and > estimate > >statements with factorial designs. It determines the order of the > variables, > >which variable changs fastest. > > > >Paul R. Swank, Ph.D. > >Professor, Developmental Pediatrics > >Medical School > >UT Health Science Center at Houston > > > > > >-----Original Message----- > >From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of > F > >Fordham > >Sent: Thursday, April 15, 2004 6:03 AM > >To: SAS-L@LISTSERV.UGA.EDU > >Subject: GENMOD, GEE, CLASS statments and the order of the variables > therein > > > > > >I've run a GEE analysis, using the following code: > > > >proc genmod data=b301wk descending; > > class trt pid poolct1c week; > > model rrelxw = poolct1c week trt week*trt / d=b link=logit; > > repeated subject=pid / type=cs within=week; > > estimate 'wk 1' week*trt 1 0 0 0 -1 0 0 0 trt 1 -1; run; > > > >All analysis runs fine, estimates are produced etc, as requested. > > > >HOWEVER - if I changed the order the variables were specified in, in > the > >class statement to " class pid poolct1c week trt;" (ie moving trt > from the > >beginning to the end of the class statement), then SAS could not > perform my > >estimate statement. > > > >I had always thought that so long as you specify all your > categorical > >variables within the class statement, that the order you specified > them in, > >did not matter. But the above 'phenomenon' has baffled me and I'm > sure > >there's a simple explanation. > > > >Can anyone help? > >TIA, > >Fiona. > > > > > > > > -- > James Algina > Professor > Educational Psychology > 1423D Norman Hall > P.O. Box 117047 > University of Florida > Gainesville, FL 32611 > > Voice 352-392-0724 x 247 > Fax 352-392-5929 > -------------------------------------------------------------------- > Please find our disclaimer at http://www.ukzn.ac.za/disclaimer > -------------------------------------------------------------------- > <<<>>> ===== --------------------------------------- Dale McLerran Fred Hutchinson Cancer Research Center mailto: dmclerra@fhcrc.org Ph: (206) 667-2926 Fax: (206) 667-5977 --------------------------------------- __________________________________ Do you Yahoo!? Yahoo! Tax Center - File online by April 15th http://taxes.yahoo.com/filing.html ------------------------------ Date: Thu, 15 Apr 2004 20:49:44 -0400 From: Lou Subject: Re: What does SAS think it's finding in this error message? "Jack Hamilton" wrote in message news:s07e8fa5.079@SLCM02.firsthealth.com... > I accidentally typed a period instead of a comma, and got this message: > > ===== > 13 if substr(_infile_, 1, 1) in ('#'. '!') then > ERROR: All variables in array list must be the same type, i.e., all > numeric or character. > ===== > > After I changed the period to a comma, the program ran correctly. > > How was SAS intrepreting the erroneous code that caused it to issue > that particular message? It thought the period was a dot - the default for a missing numeric value. ------------------------------ Date: Thu, 15 Apr 2004 21:23:15 -0400 From: Lou Subject: Re: Job control with SAS "Jack Hamilton" wrote in message news:s07d9598.037@SLCM02.firsthealth.com... > You read my question correctly - I want to be able handle concurrencies, > while running as many non-dependent programs as possible. > > I'm afraid that I don't usually write well-behaved programs, by your > definition - I rely on SAS to clean up my work data sets. In fact, I > don't think it's possible for a SAS program to completely clean out its > own WORK directory - WORK,REGSTRY and WORK.SASMACR refuse to be deleted > by PROC DATASETS KILL because they're "in use". PROC DATASETS won't get rid of catalogs. However, PROC CATALOG will delete all entries within a catalog, so in an operational sense it's as though the catalog no longer exists. Either PROC DATASETS or PROC DELETE will get rid of work datasets. Titles and footnotes are easily cleared, as are libnames and filenames. In release 6.x, it took a few lines of code to get rid of macro variables, now there's a function to do it. There's really no excuse not to do this stuff, especially if not doing it causes you or your co-workers problems. It's somewhat more difficult to reset options - you have to store an option value before you change it, and then use the stored value to reset it when you're done - it may take a whole half dozen lines of code. But hey, that's why programmers get paid the big bucks. I'm not familiar with REGISTRY entries, so can't address that item. > The plain %INCLUDE approach doesn't work for me because, although it > will run jobs in sequence, it will stop after the first failure, even > though there are non-dependent jobs remaining which could still be run. > Given > > SEQ NAME > 1 Prog1 > 1 Prog2 > 2 Prog3 > > where Prog3 is dependent on Prog1 and Prog2, if Prog1 fails then Prog2 > won't run, even though it could. I'm assuming running under windows, but I think the principles remain similar across many OS's. You bundle programs that must be executed in sequence this way. Programs that can run regardless of the success or failure of other programs are not part of the bundle, and are kicked off independently of the bundle. In this case, what I'm driving at is something like this - you have a folder, and in it are two programs. One is called FEE.SAS and reads like this: %include prog1.sas %include prog3.sas with the program names suitably qualified. The other file is prog2.sas. You open a window on that folder, press control-a to select the entire contents of the folder, right click anywhere on the selection, and click on batch submit. Prog2 will run. Prog1 will run. If an error occurs during the execution of Prog1, then Prog3 does not run. > I think SYSTASK is probably the most reasonable approach, but I've been > told offline that it sometimes results in mysterious abends; I'll have > to try it for myself. Whatever floats your boat. The last thing I'd want is mysterious abends. > > > > > > -- > JackHamilton@FirstHealth.com > Manager, Technical Development > Metrics Department, First Health > West Sacramento, California USA > > >>> Lou 04/14/2004 6:27 PM >>> > "Don Stanley" wrote in message > news:200404140152.i3E1qPu10992@listserv.cc.uga.edu... > > Few, usually, minor pitfalls to beware of with this approach > > > > (1) create a macro variable in job 1. Have a variable of the same > name in > > job 2 but forget to reset it to null in job 2. Testing job 2 > independent > of > > job 1 works fine, sequential running like below may cause very > obscure > > errors in job 2. > > A well behaved program, like a well behaved houseguest, cleans up > after > itself. No self-respecting program written by a competent programmer > would > dream of leaving work datasets, macro variables, titles, footnotes, > libnames, filenames, format or other catalogs, etc. behind. Super > proper > programs will also reset options to the status quo ante. > > If you're saddled with programmers who refuse to behave with > reasonable > politeness, you can write generic clean up code and run it after each > %included program. If you want, you can make it a program all by > itself and > %include it too. > > > (2) if errorabend is switched on and job 1 fails, then jobs 2 and 3 > will > > not run, but they would not have if running from a scheduler with no > > dependency (as originally stated by Jack some jobs can run concurrent > but > > this approach has forced them sequential) > > Maybe I misread - I took Jack to mean that his present approach > sometimes > results in programs running concurrently and that this was the problem > he > was trying to solve - some of the programs did have dependencies and > the > program n was off and running before program n-1, on which it was > dependent, > was finished. After all, he does ask if there's a way to run the jobs > "in > order". > > > (3) forces sequential running when jobs may be able to be run > together > > I guess I'm getting to be an old fuddy-duddy. Someone says "job > control" > and I immediately think Job Control Language (JCL). That's what a JCL > rundeck does - kicks off programs sequentially. If you have a bunch > of > programs that can run concurrently (and you're running windows) you > can > highlight them all, right click, and click on batch submit - job > control > isn't an issue. In this case, it seems that it is - see the previous > comment. > > > (4) I have found various abend and Task Violations to occur when > running > > large jobs with lots of macro variables sequentially like this, but > they > do > > not occur when running in parallel or in different SAS sessions. SAS > > thought a memory leak might be the problem, but absolutely no idea > when it > > could occur > > This hasn't happened to me, nor apparently to anyone else where I work > (at > least, no one has ever called it to my attention), so I can't > meaningfully > comment. > > > This is a perfectly valid use of %include, which I tried at this site > and > > discarded due to some of above issues. > > > > Don > > > > On Tue, 13 Apr 2004 21:04:03 -0400, Lou > > wrote: > > > > >Much easier, in my opinion, to just invoke each program in turn with > an > > >%include command. For instance, you could have a program file > called > "run > > >all programs.sas" that said: > > > > > >%include program1.sas > > >%include program2.sas > > >. > > >. > > >. > > > > > >Each program will be run in the order listed, and no program will > start > > >before all the preceding ones finish. You can fully qualify the > program > > >file names so that programs in various folders or in a folder > different > > from > > >the one where "run all programs.sas" is located are included. > > > > > >No new material below, included for reference only. > > > > > >"Jack Hamilton" wrote in message > > >news:s07bfe57.034@SLCM02.firsthealth.com... > > >> I have SAS programs which are usually run in sequence. It's easy > to > put > > >> the names in a file and then use the X command to run the programs > one > > >> after another, giving a sort of rudimentary job control: > > >> > > >> ===== > > >> data _null_; > > >> > > >> infile cards; > > >> > > >> input @1 jobname \$40.; > > >> > > >> now = datetime(); > > >> > > >> if jobname =: '*' or jobname =: '#' then > > >> do; > > >> put 'INFO:' now datetime16.0 ' Program skipped: ' jobname; > > >> return; > > >> end; > > >> > > >> put 'INFO: ' now datetime16.0 ' Starting ' jobname; > > >> > > >> rc = system('\$sascmd -nodms -noterminal -errorabend -rsasuser ' > || > > >> jobname); > > >> > > >> now = datetime(); > > >> if rc gt 1 then > > >> do; > > >> put 'ERROR: ' now datetime16.0 ' Return code ' rc 4.0 ' from > ' > > >> jobname; > > >> abort abend; > > >> end; > > >> else > > >> put ' ' now datetime16.0 ' Return code ' rc 4.0 ' from > ' > > >> jobname; > > >> > > >> put; > > >> > > >> cards; > > >> 01-get-dw-claims-med.sas > > >> 02-get-dw-claims-rx.sas > > >> ===== > > >> > > >> But sometimes several of the jobs could be run at the same time, > with > > >> subsequent jobs dependent on them; for example, I might have 5 > jobs > each > > >> of which processes a year's worth of data 2000-2005, and a fifth > job to > > >> combine the results. I might express the job flow like this: > > >> > > >> ----- > > >> SEQ Program > > >> 1 process-2000.sas > > >> 1 process-2001.sas > > >> 1 process-2002.sas > > >> 1 process-2003.sas > > >> 1 process-2004.sas > > >> 2 combine-years.sas > > >> ----- > > >> > > >> I could do that manually using MP CONNECT. Has anyone already > written > > >> a program (that they could share) which would read the job list > and > > >> produce the SAS code needed to process the jobs in order? I'm > lazy and > > >> don't want to reinvent it if it's already been done. > > >> > > >> > > >> > > >> > > >> > > >> > > >> > > >> -- > > >> JackHamilton@FirstHealth.com > > >> Manager, Technical Development > > >> Metrics Department, First Health > > >> West Sacramento, California USA ------------------------------ Date: Fri, 16 Apr 2004 01:34:42 GMT From: "(2B) || !(2B) Arin Chaudhuri" Subject: Re: Creating Dummy Treatment Groups Steve Zelasky wrote: > We are on XP with 8.2. > > Our study is still blinded. We have 3 treatment groups, all values for RXCD are missing in the dataset, how can I assign dummy treatment codes(1,2,3) randomly to all the patients in a given dataset. > > Thanks. > One more method data new; set old; treatment=RANTBL(0,1/3,1/3); run; ------------------------------ Date: Thu, 15 Apr 2004 22:25:39 -0400 From: James Algina Subject: Re: GENMOD, GEE,CLASS statments and the order of the variables therein This document suggested by Winston is useful as is the posting by Dale, but another recommendation is to include the solution option in the model statement. Then one sees the order of the parameter estimates in the solution vector, which will explain why Fiona's simple effect was estimable in one application of proc genmod but not the other and can be very useful in formulating estimable contrasts. Jamie Dale McLerran wrote: >Winston has pointed us in the general direction. Actually the >section on "Parameterization of PROC GLM models" is in the Details >section of the GLM procedure. We find there a section about >crossed effects which states: > > First, PROC GLM reorders the terms to correspond to the > order of the variables in the CLASS statement; thus, B*A > becomes A*B if A precedes B in the CLASS statement. Then, > PROC GLM generates columns for all combinations of levels > that occur in the data. The order of the columns is such > that the rightmost variables in the cross index faster than > the leftmost variables. No columns are generated corresponding > to combinations of levels that do not occur in the data. > > >These same rules hold throughout SAS/STAT whenever a procedure >allows crossing of variables named on a class statement. Now, >suppose that we have class variables A with 2 levels and B with >3 levels. Suppose further that we name variable A first on a >class statement. Now, let's construct the following estimates: >1) difference between a1 and a2 at each of the three levels of B, >and 2) difference between b1 and b2, b1 and b3, and b2 and b3 at >each of the two levels of A. Following the rules about crossed >effects, we would have the following estimate statements: > > a1 a1 a1 a2 a2 a2 > b1 b2 b3 b1 b2 b3 > estimate "a1-a2 @ b1" a*b 1 0 0 -1 0 0; > estimate "a1-a2 @ b2" a*b 0 1 0 0 -1 0; > estimate "a1-a2 @ b3" a*b 0 0 1 0 0 -1; > estimate "b1-b2 @ a1" a*b 1 -1 0 0 0 0; > estimate "b1-b3 @ a1" a*b 1 0 -1 0 0 0; > estimate "b2-b3 @ a1" a*b 0 1 -1 0 0 0; > estimate "b1-b2 @ a2" a*b 0 0 0 1 -1 0; > estimate "b1-b3 @ a2" a*b 0 0 0 1 0 -1; > estimate "b2-b3 @ a2" a*b 0 0 0 0 1 -1; > > >Now, if we changed the class statement so that the variable B was >listed before the variable A, then the appropriate estimate >statements would be > > b1 b1 b2 b2 b3 b3 > a1 a2 a1 a2 a1 a2 > estimate "a1-a2 @ b1" a*b 1 -1 0 0 0 0; > estimate "a1-a2 @ b2" a*b 0 0 1 -1 0 0; > estimate "a1-a2 @ b3" a*b 0 0 0 0 1 -1; > estimate "b1-b2 @ a1" a*b 1 0 -1 0 0 0; > estimate "b1-b3 @ a1" a*b 1 0 0 0 -1 0; > estimate "b2-b3 @ a1" a*b 0 0 1 0 -1 0; > estimate "b1-b2 @ a2" a*b 0 1 0 -1 0 0; > estimate "b1-b3 @ a2" a*b 0 1 0 0 0 -1; > estimate "b2-b3 @ a2" a*b 0 0 0 1 0 -1; > > >Note that if we changed the order of the variables on the class >statement but did not change the specification of the effects in >the estimate statement, we would end up with > > b1 b1 b2 b2 b3 b3 > a1 a2 a1 a2 a1 a2 > estimate "a1@b1-a2@b2" a*b 1 0 0 -1 0 0; > estimate "b1@a2-b3@a1" a*b 0 1 0 0 -1 0; > estimate "b2@a1-b3@a2" a*b 0 0 1 0 0 -1; > estimate "a1-a2 @ b1 " a*b 1 -1 0 0 0 0; > estimate "b1-b2 @ a1 " a*b 1 0 -1 0 0 0; > estimate "b1@a2-b2@a1" a*b 0 1 -1 0 0 0; > estimate "b2@a2-b3@a1" a*b 0 0 0 1 -1 0; > estimate "b2-b3 @ a2 " a*b 0 0 0 1 0 -1; > estimate "a1-a2 @ b3 " a*b 0 0 0 0 1 -1; > > >Some of these may well be inestimable. For information about >estimability, see the SAS/STAT documentation, section "The Four >Types of Estimable Functions", subsection "Estimability", >sub-subsection "General Form of an Estimable Function". > >Dale > > >--- Winston Groenewald <922424942@UKZN.AC.ZA> wrote: > > >>James, >> >>GENMOD and GLM use the same rules for constructing the design matrix. >>As such, you should be able to glean much information from the >>"Parameterisation of PROC GLM models" section in the OnLineDoc of the >>CLASS statement of GLM. >> >>Regards, >> >>Winston Groenewald >>Forestry Dept. - Science and Agriculture >>Bag X01 >>University of KwaZulu-Natal >>Scottsville >>3209 Pietermaritzburg >>27-11-260-6098 (W) >>27-11-260-6005 (F) >> >>== Rugby is for men too scared to skydive!! == >> >> >> >>>>>James Algina 04/15/04 11:29PM >>> >>>>> >>>>> >> I could not find verification of Paul's point in the help file for >>the >>class statement in genmod. Can someone tell me where this feature of >>the >>genmod class statement is explained? >> >> >> >>Paul R Swank wrote: >> >> >> >>>The order in the class statement does matter for contrasts and >>> >>> >>estimate >> >> >>>statements with factorial designs. It determines the order of the >>> >>> >>variables, >> >> >>>which variable changs fastest. >>> >>>Paul R. Swank, Ph.D. >>>Professor, Developmental Pediatrics >>>Medical School >>>UT Health Science Center at Houston >>> >>> >>>-----Original Message----- >>>From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of >>> >>> >>F >> >> >>>Fordham >>>Sent: Thursday, April 15, 2004 6:03 AM >>>To: SAS-L@LISTSERV.UGA.EDU >>>Subject: GENMOD, GEE, CLASS statments and the order of the variables >>> >>> >>therein >> >> >>>I've run a GEE analysis, using the following code: >>> >>>proc genmod data=b301wk descending; >>> class trt pid poolct1c week; >>> model rrelxw = poolct1c week trt week*trt / d=b link=logit; >>> repeated subject=pid / type=cs within=week; >>> estimate 'wk 1' week*trt 1 0 0 0 -1 0 0 0 trt 1 -1; run; >>> >>>All analysis runs fine, estimates are produced etc, as requested. >>> >>>HOWEVER - if I changed the order the variables were specified in, in >>> >>> >>the >> >> >>>class statement to " class pid poolct1c week trt;" (ie moving trt >>> >>> >>from the >> >> >>>beginning to the end of the class statement), then SAS could not >>> >>> >>perform my >> >> >>>estimate statement. >>> >>>I had always thought that so long as you specify all your >>> >>> >>categorical >> >> >>>variables within the class statement, that the order you specified >>> >>> >>them in, >> >> >>>did not matter. But the above 'phenomenon' has baffled me and I'm >>> >>> >>sure >> >> >>>there's a simple explanation. >>> >>>Can anyone help? >>>TIA, >>>Fiona. >>> >>> >>> >>> >>> >>-- >>James Algina >>Professor >>Educational Psychology >>1423D Norman Hall >>P.O. Box 117047 >>University of Florida >>Gainesville, FL 32611 >> >>Voice 352-392-0724 x 247 >>Fax 352-392-5929 >>-------------------------------------------------------------------- >>Please find our disclaimer at http://www.ukzn.ac.za/disclaimer >>-------------------------------------------------------------------- >><<<>>> >> >> > > >===== >--------------------------------------- >Dale McLerran >Fred Hutchinson Cancer Research Center >mailto: dmclerra@fhcrc.org >Ph: (206) 667-2926 >Fax: (206) 667-5977 >--------------------------------------- > > > > >__________________________________ >Do you Yahoo!? >Yahoo! Tax Center - File online by April 15th >http://taxes.yahoo.com/filing.html > > > -- James Algina Professor Educational Psychology 1423D Norman Hall P.O. Box 117047 University of Florida Gainesville, FL 32611 Voice 352-392-0724 x 247 Fax 352-392-5929 ------------------------------ Date: Fri, 16 Apr 2004 17:49:26 +0000 From: Curtis Lake Subject: Change your fate! Buy Viagra and Cialas Aka "Super Viagra"..The Viagra that last all weekend!.. and other good prescriptions....Save big on this site check it out.. Next-Day Fedex ... here at.. http://xffpc135w7.excellentrxmd.com?rid=1000 documents: consecutively Pre-Budget Reports Report. consecutively numerous documents: welfare, become ------------------------------ Date: Thu, 15 Apr 2004 22:49:54 -0400 From: "Richard A. DeVenezia" Subject: Tip: Style Gallery The style gallery macro has been improved some. Subsetting and exclusionary parts are a bit more robust. Parametric control of itemstor is still lacking. Ran ok on 9.1 doing pdf, html, and rtf. Actual output not compared closely to style definition. 8.2 runs, but not strongly recommended. %macro StyleGallery ( excludePaths = , outPath = %sysfunc(pathname(WORK)) , destination = /* common ones are - pdf | rtf | html */ , seed = 1 , file = gallery , method = ALL_IN_ONE /* ALL_IN_ONE | ONE_EACH */ ); /* Richard A. DeVenezia * April 2004 * Create a gallery of output, each item is styled according to each * specifable style. * * Note: Some styles cause Read Access Violations on some destinations. * IF YOU GET A READ ACCESS VIOLATION(RAV), EXIT YOUR SAS SESSION AND * START A NEW ONE. BEFORE SUBMITTING AGAIN, BE SURE TO EXCLUDE THE PATH * THAT CAUSED THE RAV */ %let method = %upcase (&method); %let destination = %lowcase (&destination); %if &destination = html and &method = ALL_IN_ONE %then %do; %put ERROR: destination=&destination and method=&method is incompatible; %goto EndMacro; %end; data foo; do class1 = 'a', 'b';*, 'c'; do class2 = 1 to 3; nitems = 10*ranuni(&seed); do n = 1 to nitems; var1 = ranuni (&seed); var2 = ranuni (&seed); var3+1; output; end; end; end; run; title; footnote; ods _all_ close; ods trace off; proc template; ods output Template.Stats = styles(where=(type='Style')); list ; run; %let excludePaths = %sysfunc(translate(|&excludePaths.|,|,%str( ))); %let excludePaths = %sysfunc(upcase(&excludePaths)); proc sql; delete from styles where index ("&excludePaths" , '|' || trim(upcase(path)) || '|' ) ; %local i nstyles; reset noprint; select count(*) into :nstyles from styles; %let nstyles = &nstyles; %do i = 1 %to &nstyles; %local style&i path&i; %end; select tranwrd(path,'Styles.','') into :style1-:style&nstyles. from styles ; select path into :path1-:path&nstyles. from styles ; quit; %if &method = ALL_IN_ONE %then %do; ods &destination file="&outPath./&file..&destination" ; %if &destination = pdf %then %do; ods &destination startpage=never; %end; %end; %do i = 1 %to &nstyles ; %put Render &i - &&style&i (&&path&i); %if &method = ONE_EACH %then %do; ods &destination file="&outPath./&file.-&&style&i...&destination" style=&&style&i; title "STYLE=&&style&i"; footnote "Style Gallery - Richard A. DeVenezia"; %end; %else %do; %* ALL_IN_ONE - works for pdf, not for html; ods &destination style=&&style&i; %end; proc tabulate data=foo; class class:; var var:; table class1*class2 , var1*mean var2*min var3*max / box = "#&i: Style=&&style&i" ; run; %end; %if &method = ALL_IN_ONE %then %do; ods &destination close; %end; %EndMacro: %mend; options mprint; /* * for destinations html and rtf, method ALL_IN_ONE output is not as * diverse as method ONE_EACH output ; %StyleGallery ( destination = pdf, ExcludePaths = Styles.Theme, method = ONE_EACH ) */ %StyleGallery ( destination = pdf, ExcludePaths = Styles.Theme ) %StyleGallery ( destination = html, method = ONE_EACH ) %StyleGallery ( destination = rtf, method = ONE_EACH ) -- Richard A. DeVenezia http://www.devenezia.com/downloads/sas/macros/ ------------------------------ End of SAS-L Digest - 15 Apr 2004 - Special issue (#2004-459) ************************************************************* ```

Back to: Top of message | Previous page | Main SAS-L page