LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (November 1998, week 3)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:   Thu, 19 Nov 1998 08:27:40 +0000
Reply-To:   Peter Crawford <Peter@CRAWFORDSOFTWARE.DEMON.CO.UK>
Sender:   "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From:   Peter Crawford <Peter@CRAWFORDSOFTWARE.DEMON.CO.UK>
Subject:   Re: Solution: Observation Level Resolution of Array Name
In-Reply-To:   <911438064.2019492.0@vm121.akh-wien.ac.at>

In article <911438064.2019492.0@vm121.akh-wien.ac.at>, Michael Stuart <michael.stuart@PRUDENTIAL.COM> writes >Thanks Tim B, Karsten S, and David T. for their input. > >The solution was to combine the 40 2-dim arrays into 1 3-dim array. I had >already 'standardized' the actuarial tables so they had the same number of >rows ... some of them had different row entry points, but I had inserted >dummy rows into the tables and filled with zeros. I used the same logic to >'build' the table name for each observation, then created a format to match >array name to its position within the array (i.e. format $grid 'GRID1MAX' = >1 'GRD4MCS' = 2 ... etc.) ... thus I could avoid using conditional if/thens >to determine which of 40 tables to retrieve from. > >This approach will make updating the the program for new tables slightly >more onerous, and also auditing the results, but I was able to score >records with one pass of the data. >

To eliminate any "onerous" aspect from your elegant application of array usage, use an initialising loop at the start of the data step where you use that array. Within the control of a "one-time" test ( like if _n_=1 ) have a loop to read the external file holding the meaningful rates with structure: info defining table info about entry ( like age-next ) value for corresponding entry

it would be simple SAS data step code to read such a file into the relevant elements of the array; use identical rules to generate the array subscripts for loading, as you use for referencing; it is straightforward to distinguish "0 from missing" or convert those missings to zero after the rates tables have been read; the external file can be generated from any relevant external source; it can be used by interested parties outside of a SAS context; only relevant entries are present, so you don't need zero-padding.

> > >"David Thompson" <dtas@netcomuk.co.uk> on 11/17/98 08:45:11 AM >Tuesday November 17, 1998 01:45 PM > >Please respond to "David Thompson" <dtas@netcomuk.co.uk> >To: "Michael Stuart" <michael.stuart@prudential.com> > sas-l@vm.marist.edu >cc: (bcc: Michael Stuart/M&P/Prudential) >Subject: Re: Observation Level Resolution of Array Name > > > > > >Michael, > >I agree with Karsten Self. A simple answer would be to use a >three-dimensional array (even if the individual tables are not the same >size; they would need to be padded out to the same size, though). I would >have the first dimension identifying the table, as this would allow the >data >to be initialised much as it is now. > >David Thompson >Consultant Statistician > >David Thompson Applied Statistics Tel +44 (0) 1703 620808 >105 Leigh Road Fax +44 (0) 1703 620807 >Eastleigh e-mail dtas@netcomuk.co.uk >Hampshire >SO50 9DR http://www.netcomuk.co.uk/~dtas/index.htm >United Kingdom > > >-----Original Message----- >From: Michael Stuart <michael.stuart@PRUDENTIAL.COM> >Newsgroups: bit.listserv.sas-l >To: SAS-L@VM.MARIST.EDU <SAS-L@VM.MARIST.EDU> >Date: 17 November 1998 01:12 >Subject: Observation Level Resolution of Array Name > > > >>SAS-L: I'm working on an application that calculates scores for client >>records based on individual client characteristics (straightforward, >>right?). One step in this process retrieves a value from one of 40 >>two-dimensional tables for subsequent calculations. These tables were >>created by actuaries, and therefore can't be replicated mathematically or >>through a formula (sorry, small joke). My point here is that the tables >>have to be hard coded somewhere ... I've opted to hard-code them within >the >>program as temporary arrays. A number of policy factors determine which >>table to use to retrieve values for another step ... factors such as >>product type, issue date range, etc. >> >>For each record, I can programmatically determine the name of the >temporary >>array to use, and assign it to a variable (I'm determining the array >>subscripts the same way). I'm hitting a wall now when I go to resolve the >>array reference ... I can pass variable names to the array subscripts ... >>but how do I call one of forty different arrays within a program based on >>the value of a variable (without handling through if/then)? Here's a >mucho >>simplified version of how far I've gotten: >> >>DATA TEMP ; >> >> DROP X ; >> >> ARRAY GRD1MAX{10,7} _TEMPORARY_ (07,07,07,07,07,07,06, >> 10,10,10,10,10,09,08, >> 15,15,15,15,15,15,15, >> 20,20,20,19,18,15,11, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 61,51,42,32,24,17,11); >> >> ARRAY GRD4MCS{10,7} _TEMPORARY_ (07,07,07,07,07,07,07, >> 10,10,10,10,10,10,09, >> 15,15,15,15,14,14,12, >> 20,20,20,19,19,17,13, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 00,00,00,00,00,00,00, >> 66,56,46,37,29,21,14); >> >>* GENERATE DUMMY DATA ; >> >> DO X = 1 TO 20 ; >> IF X < 11 THEN GRID2USE = 'GRD1MAX' ; >> ELSE GRID2USE = 'GRD4MCS' ; >> >> DO GRIDROW = 1 TO 10 ; >> DO GRIDCOL = 1 TO 7 ; >> >> * INSERT ARRAY CALL HERE ... AKA NEWVAR = >>GRID2USE{GRIDROW,GRIDCOL} ; >> >> OUTPUT ; >> >> END ; END ; END ; >> >>RUN ; >> >>The question ... now I've got 1400 observations in the TEMP data set with >a >>variable (GRID2USE) containing the name of the array I want to reference, >>plus the subscripts used to call the array stored in my GRIDROW and >GRIDCOL >>variables. I first tried to solve this by using call symput, but was >>annoyed to find out that you can't retrieve a macro value in the same data >>step that uses SYMPUT to assign that value. >> >>I can solve this using mutually exclusive if/then's ... but I want to >avoid >>that route because my real-world application has 40 different >>arrays/tables, and the number of tables will likely grow in future >>iterations of this project. I chose the route that got me as far as this >>because I can easily construct the name of the array I want to call within >>each observation through the following lines of code (i.e. I'm NOT using >40 >>sets of mutually exclusive if/then logic to determine which array to use): >> >> GRIDSTM1 = PUT(KIND_000,GRID.) ; >> >> GRIDSTM2 = SEX_OF_I ; >> >> GRIDSTM3 = PUT(AMT_OF_I,FACE.) ; >> >> IF GRIDSTM3 IN ('A','B') THEN GRIDSTM4 = 'X' ; >> ELSE IF SELECT_R = '1' THEN GRIDSTM4 = 'S' ; >> ELSE GRIDSTM4 = 'N' ; >> >> GRID2USE = GRIDSTM1 !! GRIDSTM2 !! GRIDSTM3 !! GRIDSTM4 ; >> >>Also -- I'm trying to accomplish all of this within one datastep ... >>ultimately this will be part of a production process running against 100s >>of millions of records ... I don't want to have to process and re-process. >> >>Insight/thoughts are appreciated -- please send a personal response to >>michael.stuart@prudential.com as well as posting to the group. Thanks in >>advance. >>

-- Peter Crawford


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