Hi,
Back to this. Two Dimensional Arrays. Can someone see why the first program works without errors and the second does not. They seem equivalent to me.
First program:
data learn.look_up; /****************************************************** Create the array, the first index is the year and it ranges from 1944 to 1949. The second index is the job code (we're using 1-5 to represent job codes A through E). *******************************************************/ array level{1944:1949,5} _temporary_; /* Populate the array */ if _n_ = 1 then do Year = 1944 to 1949; do Job = 1 to 5; input level{Year,Job} @; end; end; set learn.expose; /* Compute the job code index from the JobCode value */ Job = input(translate(Jobcode,'12345','ABCDE'),1.); Benzene = level{Year,Job}; drop Job; datalines; 220 180 210 110 90 202 170 208 100 85 150 110 150 60 50 105 56 88 40 30 60 30 40 20 10 45 22 22 10 8 ; Proc print data=learn.look_up noobs ; run ;
First Program Results.
Year Worker JobCode Benzene 1944 001 B 180 1948 002 E 10 1947 003 C 88 1945 005 A 202 1948 006 D 20
Second Program
Libname Review'/folders/myfolders/Review' ; Libname Learn'/folders/myfolders/Learn' ; Libname myformat'/folders/myfolders/sasuser.v94' ; Options fmtsearch=(myformat) ; /*Creating a Multidimensional Array*/ Proc format Library=Myformat ; Invalue LettertoNum 'A' = 1 'B' = 2 'C' = 3 'D' = 4 'E' = 5 Other = 100 ; run ; Data Review.Benzene_Levels ; Array Level{1944:1949,5} _temporary_ ; /*populates two dimensional array*/ if _n_ = 1 then do Year = 1944 to 1949; do Job = 1 to 5; input level{Year,Job} @; end; end; set learn.expose; /* Compute the job code index from the JobCode value */ Job = input(translate(Jobcode,'12345','ABCDE'),1.); Benzene = level{Year,Job}; drop Job; Datalines ; 220 180 210 110 90 202 170 208 100 85 150 110 150 60 50 105 56 88 40 20 45 22 22 10 8 ; Proc print data=Review.Benzene_Levels noobs ; run ;
Second Program Log
1 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK; 61 62 Libname Review'/folders/myfolders/Review' ; NOTE: Libref REVIEW was successfully assigned as follows: Engine: V9 Physical Name: /folders/myfolders/Review 63 Libname Learn'/folders/myfolders/Learn' ; NOTE: Libref LEARN refers to the same physical library as LEARN2. NOTE: Libref LEARN was successfully assigned as follows: Engine: V9 Physical Name: /folders/myfolders/Learn 64 Libname myformat'/folders/myfolders/sasuser.v94' ; NOTE: Libref MYFORMAT refers to the same physical library as SASUSER. NOTE: Libref MYFORMAT was successfully assigned as follows: Engine: V9 Physical Name: /folders/myfolders/sasuser.v94 65 Options fmtsearch=(myformat) ; 66 67 /*Creating a Multidimensional Array*/ 68 69 Proc format Library=Myformat ; 70 70 ! Invalue LettertoNum 71 'A' = 1 72 'B' = 2 73 'C' = 3 74 'D' = 4 75 'E' = 5 76 Other = 100 ; NOTE: Informat LETTERTONUM is already on the library MYFORMAT.FORMATS. NOTE: Informat LETTERTONUM has been output. 77 run ; NOTE: PROCEDURE FORMAT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds 78 79 Data Review.Benzene_Levels ; 80 Array Level{1944:1949,5} _temporary_ ; /*populates two dimensional array*/ 81 if _n_ = 1 then do Year = 1944 to 1949; 82 do Job = 1 to 5; 83 input level{Year,Job} @; 84 end; 85 end; 86 set learn.expose; 87 /* Compute the job code index from the JobCode value */ 88 Job = input(translate(Jobcode,'12345','ABCDE'),1.); 89 Benzene = level{Year,Job}; 90 drop Job; 91 Datalines ; NOTE: LOST CARD. RULE: ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0 97 ; Year=1949 Job=1 Worker= JobCode= Benzene=. _ERROR_=1 _N_=1 NOTE: SAS went to a new line when INPUT statement reached past the end of a line. NOTE: The data set REVIEW.BENZENE_LEVELS has 0 observations and 4 variables. NOTE: DATA statement used (Total process time): real time 0.01 seconds cpu time 0.01 seconds 97 ; 98 99 Proc print data=Review.Benzene_Levels noobs ; 100 run ; NOTE: No observations in data set REVIEW.BENZENE_LEVELS. NOTE: PROCEDURE PRINT used (Total process time): real time 0.00 seconds cpu time 0.00 seconds
Below is the code for the set learn.expose.
data learn.expose; input Worker $ Year JobCode : $1.; datalines; 001 1944 B 002 1948 E 003 1947 C 005 1945 A 006 1948 D ;
Notes:
I deeply apologize for the infile datalines truncover. This shouldn’t be used as you need the input statement to read the next line by default. Like @Astounding pointed out, you actually need another datalines to read and populate array for the dimension year(1949,1……5)
However since you have only 5 datalines, sas can’t find or read the line to populate for the year 1949.
So the correction is do year=1944 to 1948; instead of 1949
And now run and examine the corrected version below:
Data Benzene_Levels ;
Array Level{1944:1948,5} ; /*populates two dimensional array*/
retain level;
if _n_ = 1 then do Year = 1944 to 1948;
do Job = 1 to 5;
input level{Year,Job} @ ;
end;
end;
set expose;
/* Compute the job code index from the JobCode value */
Job = input(translate(Jobcode,'12345','ABCDE'),1.);
Benzene = level{Year,Job};
/* drop Job;*/
Datalines ;
220 180 210 110 90
202 170 208 100 85
150 110 150 60 50
105 56 88 40 20
45 22 22 10 8
;
Aren't you missing a line of data in the second DATA step?
data expose;
input Worker $ Year JobCode : $1.;
datalines;
001 1944 B
002 1948 E
003 1947 C
005 1945 A
006 1948 D
;
Data Benzene_Levels ;
infile datalines truncover;
Array Level{1944:1949,5} _temporary_ ; /*populates two dimensional array*/
if _n_ = 1 then do Year = 1944 to 1949;
do Job = 1 to 5;
input level{Year,Job} @;
end;
end;
set expose;
/* Compute the job code index from the JobCode value */
Job = input(translate(Jobcode,'12345','ABCDE'),1.);
Benzene = level{Year,Job};
drop Job;
Datalines ;
220 180 210 110 90
202 170 208 100 85
150 110 150 60 50
105 56 88 40 20
45 22 22 10 8
;
Ok, but isn't that data from expose already referenced by the code set learn.expose?
Yes i just ran a test in my local. That's about it
Ok Did the code I provide give you the same errors? Also, when writing infile datalines truncover, I assume this references the datalines from review.Benzene_levels, not from expose.
Anyway, no matter what I will accept your solution and give you points. Just trying to understand this. Thanks for your help.
@ManitobaMoose Haha, no you should NOT accept as solution that's not convincing. These credits definitely don't matter, it's just for learning.
Be right back in a bit with a detailed explanation as I am having a burger on one hand, and am finding hard to type
Notes:
I deeply apologize for the infile datalines truncover. This shouldn’t be used as you need the input statement to read the next line by default. Like @Astounding pointed out, you actually need another datalines to read and populate array for the dimension year(1949,1……5)
However since you have only 5 datalines, sas can’t find or read the line to populate for the year 1949.
So the correction is do year=1944 to 1948; instead of 1949
And now run and examine the corrected version below:
Data Benzene_Levels ;
Array Level{1944:1948,5} ; /*populates two dimensional array*/
retain level;
if _n_ = 1 then do Year = 1944 to 1948;
do Job = 1 to 5;
input level{Year,Job} @ ;
end;
end;
set expose;
/* Compute the job code index from the JobCode value */
Job = input(translate(Jobcode,'12345','ABCDE'),1.);
Benzene = level{Year,Job};
/* drop Job;*/
Datalines ;
220 180 210 110 90
202 170 208 100 85
150 110 150 60 50
105 56 88 40 20
45 22 22 10 8
;
Ok. Great. Now it make sense. The data set learn.update is from the Book Learning SAS by Example, and it worked, but it appears that the array range for year should have been 1944 to 1948. Perhaps it is an error in the book, even though it seems to work. At any rate, it appears that this is the genesis of the problem. Everything works now. Excellent learning experience. Thanks for your help.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.