BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
smw10
Fluorite | Level 6

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

1 ACCEPTED SOLUTION

Accepted Solutions
art297
Opal | Level 21

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

 

View solution in original post

12 REPLIES 12
ballardw
Super User

@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;
data_null__
Jade | Level 19

Because OUTPUT;

Tom
Super User Tom
Super User

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
;

 

smw10
Fluorite | Level 6

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.

art297
Opal | Level 21

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
Fluorite | Level 6

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."

art297
Opal | Level 21

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

smw10
Fluorite | Level 6

Thank you!!!

smw10
Fluorite | Level 6

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?

Tom
Super User Tom
Super User

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;
smw10
Fluorite | Level 6

I completely understand now. Thanks!

art297
Opal | Level 21

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

 

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 1216 views
  • 0 likes
  • 5 in conversation