"DeckArrays" in CSPro is a simplified way of working with hot decks. It is important to understand the hot deck process well before using DeckArrays, because the functions
getdeck and
putdeck automatically handle recodes and thus hide much of the hot deck behavior from the programmer. DeckArrays eliminate the need for the programmer to recode variables to fit within the boundaries of an array, as the recodes are processed automatically based on values defined within a
value set .
Using DeckArrays makes it very easy to change hot deck parameters. For instance, if a subject-matter specialist decides that a variable should be hotdecked based on five-year age intervals but later changes the specification to ten-year age intervals, programming will be trivial if using DeckArrays, whereas with standard hot decks reprogramming the recodes may be time-consuming.
Declare a DeckArray in
PROC GLOBAL as you would a normal array, but instead of using numeric dimensions, specify the name of a value set. The size of the dimension will match the size of the value set. If you make changes to the value set, the size of the array will automatically reflect the changes.
Array Age_HD_from_Sex(SEX_VS); // same as "Array Age_HD_From_Sex(2);" Array Age_HD_from_Sex_Relationship(SEX_VS, RELATIONSHIP_VS);
To create a DeckArray, at least one of the dimensions must be a
value set ; however, it is permissible that the other dimensions are declared with a numeric value. Because the program can only recode values for the dimensions that are based on value sets, for any dimensions that were declared with a number, it will be necessary to specify those indices explicitly when making calls to
getdeck or
putdeck.
Array Age_HD_from_EA_Sex(200, SEX_VS); // same as "Array Age_HD_From_EA_Sex(200,2);"
Occasionally a programmer wants to create a hot deck with a
"leftover" row for any values not contained in the value set. Sometimes these are invalid values, other times the value set can be created so that this leftover, or "else" row, consists of values valid for the census or survey. For instance, if a user wants to hot deck a variable based on Christian sects, the programmer would create a value set with all the Christian sects, and then would create a DeckArray with a leftover row for all people who do not belong to the Christian sects identified. Including this extra "spillover" row is indicated by adding a (+) after the value set name.
Array CEB_HD_Religion (RELIGION_CHRISTIAN_SECTS_VS(+));
This is a very simplified edit specification: If the head of household's age is missing or invalid, the value should be imputed with a hot deck based on the head's sex and the spouse's age. If there is no spouse or the spouse's age is invalid, the logic will hot deck based on the head's sex and the household size, which we have set to a max of 10. If the household has more persons than that, we will cap it at 10.
PROC GLOBAL
numeric maxHHSize = 10;
Array HD_HeadAgeFromHHSize(SEX_VS, 10); // household size is from 1-10
Array HD_HeadAgeFromSpouse(SEX_VS, AGE_VS); // dims = Head's sex + Spouse's age
PROC AGE
universe RELATIONSHIP = 1; // we're only editing head of households here
// assumption: by now RELATIONSHIP and SEX have been edited for the head of HH
numeric ptrSpouse = seek(RELATIONSHIP = 2); // code 2 means spouse
numeric minSpouseAge = 12;
if SEX = 1 then
minSpouseAge = 15; // males cannot marry until 15
endif;
if AGE in 15:95 then // the head of HH has a valid age
// Then we can update the hot deck based on the head's sex and HH size.
// Note if there are more than 10 persons in the HH we are capping it at 10
putdeck(HD_HeadAgeFromHHSize,AGE,SEX,low(totocc(),maxHHSize)); // update the hot deck
putdeck(HD_HeadAgeFromHHSize,AGE, ,low(totocc(),maxHHSize)); // same as above
// now let's see if we can update the other hot deck based on the spouse's age
if ptrSpouse <> 0 and AGE(ptrSpouse) in minSpouseAge:95 then
// the spouse has a valid age
putdeck(HD_HeadAgeFromSpouse, AGE, SEX, AGE(ptrSpouse)); // update the hot deck
putdeck(HD_HeadAgeFromSpouse, AGE, , AGE(ptrSpouse)); // same as above
// Because SEX is located in the current record, and we are currently
// processing the head of HH, we don't need to pass in the head of HH's
// sex--it can be left blank and CSPro will pick the correct value, since
// we defined that array position using the SEX_VS above.
// Note the age of the spouse must always be passed to putdeck, because
// we are updating the hot deck based on the spouse's age, not the head
// of HH's age (don't forget we will use this hot deck when the age of
// the head is invalid)
endif;
else // the head of household's age is invalid so we must impute it
if ptrSpouse <> 0 and AGE(ptrSpouse) in minSpouseAge:95 then
// the spouse has a valid age, use the spouse hot deck to retrieve an age for the head
impute (AGE, getdeck (HD_HeadAgeFromSpouse, , AGE(ptrSpouse) ) );
else
// the spouse didn't have a valid age, use the other hot deck
// based on the size of the household
impute (AGE, getdeck (HD_HeadAgeFromHHSize, low(totocc(),maxHHSize) ) );
endif;
endif;
SEX_VS has two values: 1 (Male) and 2 (Female)
EDUC_VS has three values: 1 (No schooling), 2 (Primary schooling), 3 (Secondary schooling)
// Command: // The hot deck looks like
// this after the command:
Array ageHotdeck(SEX_VS,EDUC_VS(+)); // 00 00 00 00
// 00 00 00 00
SEX = 1; EDUC = 1; AGE = 20; // 20 00 00 00
putdeck(ageHotdeck,AGE); // 00 00 00 00
SEX = 2; EDUC = 3; AGE = 50; // 20 00 00 00
putdeck(ageHotdeck,AGE); // 00 00 50 00
SEX = 1; EDUC = 8; AGE = 64; // 20 00 00 64
putdeck(ageHotdeck,AGE); // 00 00 50 00
SEX = 2; EDUC = 3; AGE = notappl; // 20 00 00 64
AGE = getdeck(ageHotdeck); // AGE = 50 // 00 00 50 00
SEX = 2; EDUC = 0; AGE = 10; // 20 00 00 64
putdeck(ageHotdeck,AGE); // 00 00 50 10
SEX = 2; EDUC = 0; AGE = 11; // 20 00 00 64
putdeck(ageHotdeck,AGE,SEX); // 00 00 50 11
SEX = 2; EDUC = 0; AGE = 12; // 20 00 00 64
putdeck(ageHotdeck,AGE,SEX); // 00 00 50 12
SEX = 2; EDUC = 0; AGE = 13; // 20 00 00 64
putdeck(ageHotdeck,AGE,,EDUC); // 00 00 50 13
SEX = 2; EDUC = 0; AGE = 14; // 20 00 00 64
putdeck(ageHotdeck,AGE,SEX,EDUC); // 00 00 50 14
putdeck(ageHotdeck,28,1,3); // 20 00 28 64
// 00 00 50 14
putdeck(ageHotdeck,28,0,3); // returns // 20 00 28 64
// DEFAULT because 0 is not in SEX_VS // 00 00 50 14
// and no (+) was specified for SEX_VS
// 20 00 28 64
AGE = getdeck(ageHotdeck,2,300); // AGE = 14 // 00 00 50 14