Hi everyone. I asked a similar question earlier but this one is different. I have posted the code and output below. I don't get how this is leading to this output. I thought it would work like this: The @ sign would hold the the data on the first line after reading in Dehli as the value for the first observation of city. Then quarter would equal 1. Then, rain would equal 50. Since there is an @ sign after rain, I thought this would make sure that it stays reading observation one, replacing the value of city (previously Dehli) with 45, replacing quarter with 2, and replacing rain with 55, and the process would repeat and would output only one observation. Why isn't this the case? Additionally, when I remove the @ sign after rain, why does it lead to only one observation being read in? If someone can dumb done the process for me it would be highly appreciated.
code:
data data1;
infile cards;
input city :$ @;
do quarter =1 to 4 ;
input rain @;
output;
end;
cards;
delhi 50 45 55 67
;
run;
output:
Obs city quarter rain
1 delhi 1 50
2 delhi 2 45
3 delhi 3 55
4 delhi 4 67
I think you're responding to @Tom's description, but the same holds for my description and SAS processing in general. What you're missing is understanding the implicit loop in every datastep operation. All values are kept, unless intentionally overwritten by the user, UNTIL the process gets to the end of the datastep (thus, iterates to the next record, if any). It is only at that point (unless the datastep contains a retain statement), that the values are set to missing.
Art, CEO, AnalystFinder.com
@smw10 wrote:
<Edited>
@the @ sign would hold the the data on the first line after reading in Dehli as the value for the first observation of city. Then quarter would equal 1. Then, rain would equal 50. Since there is an @ sign after rain, I thought this would make sure that it stays reading observation one, replacing the value of city (previously Dehli) with 45, replacing quarter with 2, and replacing rain with 55,
<That is exactly what happened. And your OUTPUT statement tells SAS to write to the data set at each iteration.>
If
and the process would repeat and would output only one observation. Why isn't this the case? <OUTPUT is executable, so each time it is encountered you get things written to the data set. If you expected to have 4 values for quarter and rain you need to strore them in 4 separate variable. Basic rule for SAS data sets One observation, one value per variable>
@Additionally, when I remove the @ sign after rain, why does it lead to only one observation being read in? If someone can dumb done the process for me it would be highly appreciated.
code:
data data1;
infile cards;
@input city :$ @;
do quarter =1 to 4 ;
@input rain @;
output;
end;cards;
delhi 50 45 55 67
;
run;
output:
Obs city quarter rain
1 delhi 1 50
2 delhi 2 45
3 delhi 3 55
4 delhi 4 67
Were you wanting/expecting something like:
data data1; infile cards; input city :$ @; array qtr {4}; Array R {4} rain1-rain4; do i =1 to 4 ; input rain @; qtr[i]=i; r[i]=rain; end; cards; delhi 50 45 55 67 ; run;
Because OUTPUT;
The trailing @ sign tells the INPUT statement that you are NOT finished with that line of input text.
The reason you only get one observation when you remove the trailing @ from the second INPUT statement is because SAS will stop the data step when the INPUT statement reads past the end of the input lines. So when QUARTER=2 the data step stops at the INPUT RAIN statement and doesn't get to the OUTPUT statement to write another observation.
If you removed the trailing @ from both INPUT statements then your data lines would need to look like this:
cards;
delhi
50
45
55
67
;
Thank you for your answer. I just want to clarify to see if I understand:
The @ at the end of "input city :$ @;" means that we are going to stay on the first row of the datalines statement, "delhi 50 45 55 67," after assigning Dehli to the variable city (since, after an input statement, without the @ sign we would skip to the second row of data which in this case there is none). Next, we enter a loop with the first iteration being quarter=1 and rain=45.
What I don't understand is how city retains its value across all 4 observations and how, after the first output within the do loop, that it knows to move on and to create a second observation where quarter=2 and rain=55. Sorry if I'm not understanding everything quickly.
I think you're responding to @Tom's description, but the same holds for my description and SAS processing in general. What you're missing is understanding the implicit loop in every datastep operation. All values are kept, unless intentionally overwritten by the user, UNTIL the process gets to the end of the datastep (thus, iterates to the next record, if any). It is only at that point (unless the datastep contains a retain statement), that the values are set to missing.
Art, CEO, AnalystFinder.com
Art, this has helped me a lot! Thank you so much for always being an amazing contributor. Now I understand why it is retaining the style value. One last thing, can you explain how it knows to move on to create a second observation? I realize the @ sign after rain makes it stay on the line "delhi 50 45 55 67." However, I don't know how it knows to create a second observation of "Dehli,2,45" without just overwriting the first observation, "dehli,1,50."
Like @data_null__said, the output statement writes the then current values to Data1. Each time SAS see an output statement, it will create a new record in Data1.
Art, CEO, AnalystFinder.com
Thank you!!!
Art, not to be annoying, but I tested it out and removing the output statement resulted in one observation as expected. What was unexpected is that the observation had a value of "5" for quarter. Do you know why it is doing this?
A DO loop test after the increment. So it runs the code inside the loop when QUARTER=4 increments it to 5 and then exits the DO loop.
Try running some code to see what is happening.
data _null_;
do i=1 to 9 by 3 ;
put 'in loop' i= ;
end;
put 'after loop' i=;
run;
I completely understand now. Thanks!
You asked for a "dumbed down" explanation .. I'll try the best I can.
First, realize, that SAS alway has an implicit loop running behind the data step.
Here is the code I ran to provide a background for my example:
data data1; infile cards; input city :$ @; do quarter =1 to 4 ; input rain @; output; end; cards; delhi 50 45 55 67 albany 20 25 50 70 ;
For the first iteration, SAS gets to work with "
delhi 50 45 55 67
It reads the city as delphi, but then is told to stop at character #6;
Then it's told to read 50 into a variable called rain, stop at character 9, and output a record containing City=Delphi and Rain=50.
Then it's told to read 45 into a variable called rain, stop at character 12, and output a record containing City=Delphi and Rain=45.
Then it's told to read 55 into a variable called rain, stop at character 15, and output a record containing City=Delphi and Rain=55.
Then it's told to read 67 into a variable called rain, stop at character 18, and output a record containing City=Delphi and Rain=67.
Then it reaches the end of the first implied loop, sets both City and Rain to missing, and repeats the above process on the second data record (i.e.,
albany 20 25 50 70
Art, CEO, AnalystFinder.com
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.