In a nested file, the record types are related to each other hierarchically. The record types are grouped together by a case identification number that identifies the highest level—the first record type—of the hierarchy. Usually, the last record type specified—the lowest level of the hierarchy—defines a case. For example, in a file containing information on a company’s sales representatives, the records could be grouped by sales region. Information from higher record types can be spread to each case. For example, the sales region information can be spread to the records for each sales representative in the region.
Example
In this example, sales data for each sales representative are nested within sales regions (cities), and those regions are nested within years.
*nested_file1.sps.
- DATA LIST / SalesRep 3-13 (A) Sales 20-23.
END FILE TYPE.
END DATA.
Figure 3-13
Nested data displayed in Data Editor
The commands that define how to read the data are all contained within theFILE TYPE–END FILE TYPEstructure.
NESTEDidentifies the type of data file.
The value that identifies each record type is a string value in column 1 of each record.
The order of theRECORD TYPEand associatedDATA LISTcommands defines the nesting hierarchy, with the highest level of the hierarchy specified first. So,'Y'(year) is the highest level, followed by'R'(region), and finally'P'(person).
Eight records are read, but one of those contains year information and two identify regions; so, the active dataset contains five cases, all with a value of 2002 for Year, two in the Chicago Region and three in Baton Rouge.
Using INPUT PROGRAM to Read Nested Files
The previous example imposes some strict requirements on the structure of the data. For example, the value that identifies the record type must be in the same location on all records, and it must also be the same type of data value (in this example, a one-character string).
Instead of using aFILE TYPEstructure, we can read the same data with anINPUT PROGRAM, which can provide more control and flexibility.
Example
This first input program reads the same data file as theFILE TYPE NESTEDexample and obtains the same results in a different manner.
* nested_input1.sps.
INPUT PROGRAM.
- DATA LIST FIXED END=#eof /#type 1 (A).
- DO IF #eof.
- END FILE.
- END IF.
- DO IF #type='Y'.
- REREAD.
- DATA LIST /Year 3-6.
- LEAVE Year.
- ELSE IF #type='R'.
- REREAD.
- DATA LIST / Region 3-13 (A).
- LEAVE Region.
- ELSE IF #type='P'.
- REREAD.
- DATA LIST / SalesRep 3-13 (A) Sales 20-23.
- END CASE.
The commands that define how to read the data are all contained within theINPUT PROGRAM structure.
The firstDATA LISTcommand reads the temporary variable #type from the first column of each record.
END=#eofcreates a temporary variable named #eof that has a value of 0 until the end of the data file is reached, at which point the value is set to 1.
DO IF #eofevaluates as true when the value of #eof is set to 1 at the end of the file, and an END FILEcommand is issued, which tells theINPUT PROGRAMto stop reading data. In this example, this isn’t really necessary, since we’re reading the entire file; however, it will be used later when we want to define an end point prior to the end of the data file.
The secondDO IF–ELSE IF–END IFstructure determines what to do for each value of type.
REREADreads the same record again, this time reading either Year, Region, or SalesRep and Sales, depending on the value of #type.
LEAVEretains the value(s) of the specified variable(s) when reading the next record. So the value of Year from the first record is retained when reading Region from the next record, and both of those values are retained when reading SalesRep and Sales from the subsequent records in the hierarchy. Thus, the appropriate values of Year and Region are spread to all of the cases at the lowest level of the hierarchy.
END CASEmarks the end of each case. So, after reading a record with a #type value of'P', the process starts again to create the next case.
Example
In this example, the data file reflects the nested structure by indenting each nested level; so the values that identify record type do not appear in the same place on each record. Furthermore, at the lowest level of the hierarchy, the record type identifier is the last value instead of the first. Here, anINPUT PROGRAMprovides the ability to read a file that cannot be read correctly byFILE TYPE NESTED.
*nested_input2.sps.
INPUT PROGRAM.
- DATA LIST FIXED END=#eof
/#yr 1 (A) #reg 3(A) #person 25 (A).
- DO IF #eof.
- DATA LIST / SalesRep 7-17 (A) Sales 20-23.
- END CASE.
This time, the firstDATA LISTcommand reads three temporary variables at different locations, one for each record type.
TheDO IF–ELSE IF–END IFstructure then determines how to read each record based on the values of #yr, #reg, or #person.
The remainder of the job is essentially the same as the previous example.
Example
Using the input program, we can also select a random sample of cases from each region and/or stop reading cases at a specified maximum.
*nested_input3.sps.
- ELSE IF #person='P' AND UNIFORM(1000) < 500.
- REREAD.
- DATA LIST / SalesRep 7-17 (A) Sales 20-23.
- END CASE.
- COMPUTE #count=#count+1.
- END IF.
END INPUT PROGRAM.
BEGIN DATA
NUMERIC #count (F8)uses a scratch (temporary) variable as a case-counter variable.
Scratch variables are initialized to 0 and retain their values for subsequent cases.
ELSE IF #person='P' AND UNIFORM(1000) < 500will read a random sample of approximately 50% from each region, sinceUNIFORM(1000)will generate a value less than 500 approximately 50% of the time.
COMPUTE #count=#count+1increments the case counter by 1 for each case that is included.
DO IF #eof OR #count = 1000will issue anEND FILEcommand if the case counter reaches 1,000, limiting the total number of cases in the active dataset to no more than 1,000.
Since the source file must be sorted by year and region, limiting the total number of cases to 1,000 (or any value) may omit some years or regions within the last year entirely.