Looping is essential to statistical programming. Whether you need to iterate over parameters in an algorithm or indices in an array, a loop is often one of the first programming constructs that a beginning programmer learns.
Today is the first anniversary of this blog, which is named The DO Loop, so it seems appropriate to blog about DO loops in SAS. I'll describe looping in the SAS DATA step and compare it with
looping in the SAS/IML language.
Loops in SAS
Loops are fundamental to programming because they enable you to repeat a computation for various values of parameters. Different languages use different keywords to define the iteration statement. The most well-known statement is the "for loop," which is used by C/C++, MATLAB, R, and other languages. Older languages, such as FORTRAN and SAS, call the iteration statement a "do loop," but it is exactly the same concept.
DO loops in the DATA step
The basic
iterative DO statement in SAS has the syntax
DO value = start TO stop. An END statement marks the end of the loop, as shown in the following example:
data A;
do i = 1 to 5;
y = i**2; /* values are 1, 4, 9, 16, 25 */
output;
end;
run; |
By default, each iteration of a DO statement increments the value of the counter by 1, but you can use the BY option to increment the counter by other amounts, including non-integer amounts. For example, each iteration of the following DATA step increments the value
i by 0.5:
data A;
do i = 1 to 5 by 0.5;
y = i**2; /* values are 1, 2.25, 4, ..., 16, 20.25, 25 */
output;
end;
run; |
You can also iterate "backwards" by using a negative value for the BY option:
do i=5 to 1 by -0.5.
DO loops in SAS/IML Software
A basic
iterative DO statement in the SAS/IML language has exactly the same syntax as in the DATA step, as shown in the following PROC IML statements:
proc iml;
x = 1:4; /* vector of values {1 2 3 4} */
do i = 1 to 5;
z = sum(x##i); /* 10, 30, 100, 354, 1300 */
end; |
In the body of the loop,
z is the sum of powers of the elements of
x.
During the
ith iteration, the elements of
x are raised to the
ith power. As mentioned in the previous section, you can also use the BY option to increment the counter by non-unit values and by negative values.
Variations on the DO loop: DO WHILE and DO UNTIL
On occasion, you might want to stop iterating if a certain condition occurs.
There are two ways to do this: you can use the WHILE clause to iterate
as long as a certain condition holds, or you can use the UNTIL clause to iterate
until a certain condition holds.
You can use the DO statement with a WHILE clause to iterate while a condition is true. The condition is checked before each iteration, which implies that you should intialize the stopping condition prior to the loop. The following statements extend the DATA step example and iterate as long as the value of
y is less than 20. When
i=4, the WHILE condition is not satisfied, so the loop iterates again.
data A;
y = 0;
do i = 1 to 5 by 0.5 while(y < 20);
y = i**2; /* values are 1, 2.25, 4, ..., 16, 20.5 */
output;
end;
run; |
You can use the iterative DO statement with an UNTIL clause to iterate until a condition becomes true. The UNTIL condition is evaluated at the end of the loop, so you do not have to initialize the condition prior to the loop. The following statements extend the PROC IML example. The iteration stops after the value of
z exceeds 200.
proc iml;
x = 1:4;
do i = 1 to 5 until(z > 200);
z = sum(x##i); /* 10, 30, 100, 354 */
end; |
In these examples, the iteration stopped because the WHILE or UNTIL condition was satisfied. If the condition is not satisfied when
i=5 (the last value for the counter), the loop stops anyway. Consequently, the examples have two stopping conditions: a maximum number of iterations and the WHILE or UNTIL criterion. SAS also supports a
DO WHILE and
DO UNTIL syntax that does not involve using a counter variable.
It is worth noting that a DO loop with an UNTIL clause
always executes at least one time because the condition is evaluated at the end of the loop. To prevent this behavior, use a DO loop with a WHILE clause.
Looping over a set of items (foreach)
Some languages support a "foreach loop" that iterates over objects in a collection. SAS doesn't support that syntax directly, but there is a variant of the DO loop in which you can iterate over values in a specified list. The syntax in the DATA step is to specify a list of values (numeric or character) after the equal sign. The following example iterates over a few terms in the Fibonacci sequence:
data A;
do v = 1, 1, 2, 3, 5, 8, 13, 21;
y = v/lag(v);
output;
end;
run; |
The ratio of adjacent values in a Fibonacci sequence converges to the golden ratio, which is 1.61803399....
The SAS/IML language does not support this syntax, but does enable you to iterate over values that are contained in a vector (or matrix). The following statements create a vector,
v, that contains the Fibonacci numbers. An ordinary DO loop is used to iterate over the elements of the vector. At the end of the loop, the vector
z contains the same values as the variable Y that was computed in the DATA step.
proc iml;
v = {1, 1, 2, 3, 5, 8, 13, 21};
z = j(nrow(v),1,.); /* initialize ratio to missing values */
do i = 2 to nrow(v);
z[i] = v[i]/v[i-1];
end; |
Avoid unnecessary loops in the SAS/IML Language
I have some advice on using DO loops in SAS/IML language: look carefully to determine if you really need a loop.
The SAS/IML language is a matrix/vector language, so statements that operate on a few long vectors run much faster than equivalent statements that involve many scalar quantities. Experienced SAS/IML programmers rarely operate on each element of a vector. Rather, they manipulate the vector as a single quantity. For example, the previous SAS/IML loop can be eliminated:
proc iml;
v = {1, 1, 2, 3, 5, 8, 13, 21};
idx = 2:nrow(v);
z = v[idx]/v[idx-1]; |
This computation, which computes the nonmissing ratios, is more efficient than looping over elements. For other tips and techniques that make your SAS/IML programs more efficient, see my book
Statistical Programming with SAS/IML Software.
SUBSCRIBE TO THE SAS TECH REPORT
110 Comments
it have an algorithm likely the last one but for DO WHILE?.
i.e.
proc iml);
v = {1, 1, 2, 3, 5, 8, 13, 21};
idx = 2:nrow(v);
z = v[idx]/v[idx-1];
but for DO WHILE. For example i think using the LOC function.... Note: In the algorithm the ")" is wrong...
Thaks.
Hello;
I have a small problem which I think can be solved by loops in SAS, but I don't know how, I appreciate if you help me with that:
I have a data set in which if a value is missing then it shall be assigned the nearest non missing value in the previous observations, for example, 6 rows of my data looks like this:
1
.
.
2
.
4
I want to assign the missing values so that it would read like this
1
1
1
2
2
4
Can SAS do that for me?
Yes, of course. Direct questions like this to the SAS Community Forum on DATA step programming..
@Oscar: Here is the solution to your question.
*data set b4 with variable a as you have;
data b4;
a=1;output;
a=.;output;
a=.;output;
a=2;output;
a=.;output;
a=4;output;
run;
data after;
retain b;
set b4;
if not missing(a) then b=a;
run;
*data set after has variable b as you required;
In sas Using an array how to find the sum of higest two HWs from HW1--HW4
For help with SAS DATA step programming, post your questions to the SAS DATA step community.
sir, i have a question like cost of vehicle is 5000 and income every day is 100..how many days he will purchase the vehicle ..can we do this by using do until?
Yes, you could do that. It might look like this:
do day=1 to 1000 until(pay>=cost);
...
How do I create a column sequential as counter lines in SAS programming?
I don't understand what you are asking, but you can post questions and have discussions about SAS programming at the SAS Support Community.
Try with:
DATA b;
SET a;
SEQ+1;
RUN;
data one;
input name $ seq;
datalines;
sada 12
sada2 13
sada3 14
;run;
data two ;
set one
seq+1;
run;
output
sada 13
sada2 14
sada3 15
i have a question:
data _null_;
whereishi=0;
do until(whereishi=0);
if whereishi=0 then put "The End";
end;
run;
even though the do loop is satisfying intially with zero still it is looping,i could see in log The end .How come?
As the article says, "the UNTIL condition is evaluated at the end of the loop." This implies that an UNTIL loop always executes at least once. In contrast, a WHILE loop will not execute if the condition is false.
Why this code is not working, Basically I am splitting the data, When I was trying to print one of them, its showing the data set is not created, could anyone help on the same.
%MACRO DO_SQL;
%DO i = 1 %TO 10;
PROC SQL;
CREATE TABLE itemdef_&i AS
SELECT var2
FROM three
WHERE unique_key = "itemdef.&i";
QUIT;
%END;
%MEND DO_SQL;
PROC PRINT DATA = itemdef_1;
RUN;
You can ask questiones about SAS programming at the SAS Support Communities.
I have a column for each employee start date (startdt1 thru startdt12) in a new position, and a column for their last promotion date. How can I create a loop that will tell me when the promotion date is between startdt(i) and startdt(i+1) and output to a new variable with "Start_DT(i)" ? Thanks.
I suspect you'll want to use an ARRAY and loop over the 12 variables. Ask this question at a SAS Support Community such as https://communities.sas.com/community/support-communities/sas_macro_facility_data_step_and_sas_language_elements
Thank you
Perhaps this is not something the DO LOOP command does, but I am looking for an elegant way to repeat an analysis, though changing the outcome in each analysis. I'm using proc glimmix and need to model ~50 outcomes and would like to avoid the tedium of waiting for the run to complete, changing the outcome, running again... If the loop command doesn't do this, can anyone refer me to the command (or macro) that does (if there is one)? Thanks, Mark
1) It sounds like you want to use the BY statement, which loops over all values of a discrete variable such as US states or the numbers 1-50.
2) If you are doing a simulation, you might want to read about the advantage of the BY statement over macro loops.
3) If I haven't answered your question, post your question to the SAS Support Community
Hi Rick - Thank you for your prompt reply. I don't think the BY statement will do what I'm looking for: I need to run models across different outcome variables, not different values of one outcome variable. Thanks for the reference to the SAS Support Community; I'll try that next. Best, M
OK, good luck. If the explanatory variables and form of the model are the same for each, you can use a macro %DO loop, but I still think the most efficient option is to concatenate the data set and use a BY statement. Instead of N obsevations that look like
Y1 Y2 ... Y50 X1 X2 .. Xk
you will stack the data and have 50*N observations that look like this:
1 Y1 X1 X2 .. Xk
...
2 Y2 X1 X2 .. Xk
...
50 Y50 X1 X2 .. Xk
Rick I am wondering (1) can I use the do -loop when i have got n variables, lets say X1,X2,...,Xn, and i would like to introduce a new variable Z s.t. Z=X1+X2+X3+...+Xn
(2) If there is any hidden(or obvious that I have not notice) problem when I delete the continue word and the whole leave statement in the following programme written:
"data q1;
i = 100;
do while (1);
i = i - 2;
if mod(i,6)=0 then do;
output;
continue;
end;
if mod(i,4)=0 then do;
output;
continue;
end;
if mod(i,7)=0 and mod(i,5)=0 then leave;
end;
run;"
the thoughts are driving me crazy!
When SAS questions are driving you crazy, post your question to one of the many SAS Support Communities.
Hi Rick ,
my query is i have table ABC in which one column name is table_name which contains n different tables names. I want to create a separate data sets for the corresponding table names. can you please help me with this.
See my previous response. Go to the SAS Support Communities to get answers to questions like this.
Hi Rick,
I have a dataset with 3 columns, Customer ID, Product Key and Sales. Could you please advise how I can convert the table into something like the following:
Customer ID, Key1 _Sales, Key2_Sales, Key3_Sales, and so on.
Thank you for your help in advance.
Amy
Ask questions like this at the SAS Support Communities.
This particular question will require PROC TRANSPOSE, so it is suitable for the SAS Procedures Community.
I am a new user in SAS. When I am using DO-LOOP in SAS, I get a hesitation with the use in SET dataset. Simply speaking, I would like to know the following difference in the result:
**** input data source;
data a;
input name $1-10 test 12-15 score 17-22;
datalines;
Kitty 1 70
David 1 80
May 1 95
David 3 .
May 3 95
David 2 85
Kitty 3 .
Kitty 2 90
May 2 95
;
proc sort; by name test;
run;
*e.g. 1 : set dataset outside do-loop, and 9 observations are included in data temp;
data temp;
set a;
do x=1 to 10;
y=x;
end;
run;
*e.g. 2 : set dataset inside do-loop, and 1 observation (_N_=10) is included only in data temp;
data temp;
do x=1 to 10;
set a;
y=x;
end;
run;
May I thank those who can solve my weakness in SAS.
That's a good question. Understanding these cases requires a discussion of the implicit loop in the DATA step, and how SET, DO loops, and the OUTPUT statement interact. I suggest you post this and future questions to the SAS Support Community.
Rick,
I want to read a file sequentially, and then for each row on that file, using data from that row, perform an SQL proc to retrieve data associated with that data, to write out all of the data.
IE: how do I loop through the SQL proc for each row on the input sequential file?
You can ask questions and post example data at the SAS Support Communities. For SQL questions, post to the community for "Macro, DATA Step, and SAS Language Elements."
Hi all,
I have data for stocks (stock prices, returns, abnormal returns and cumulative abnormal returns) for the period 31 Jan 2007 and 31 Dec 2013. I have further given each date a stock Month Number (StockMonthNumber).
So, I now want sas to given me the mean, median, t-stat and p-value for my CumulativeAbnormalReturns only for up to month 6. How do I do this?
Do I say:
Proc univariate date=work.thokozani;
var CummulativeAbnormalReturns;
Where StockMonthNumber<=6;
run;
You can ask questions like this at the SAS Support Communities.
I am trying to calculate the following.
price=lag(price)*cpi/100. I have hand-calculated the price for the year 1979: 102.6133=101.19x100.07/100. The next year (1980) should be 102.6133*107.5/100. What is the SAS algorithm?
year cpi price
1978 100.07 100.07
1979 101.19 102.6133
1980 107.5 ?
1981
...
You can ask statistical ad programming questions at the SAS Support Communities.
I want to simulate a bivariate dataset (say weight vs blood pressure) with normal distribution, after which I would like to create a missing completely at random scenario with certain observations in the blood pressure variables missing. I would then like to perform mean imputation (or multiple imputation) for the missing observations to compare the mean and variance between the original (before missingness was induced) and the imputed dataset. I intend to do this multiple of times to get the average mean and variance for the imputed data, for the comparison with the original. I feel I could do this using SAS but can't figure out how, because I am a very basic user.
Could any one help figure out how I could do that please?
Yes, you should post your question to the SAS Support Communities.
what is wrong with my macro code, I want to create 36 versions of gb flag
HELP, PLEASE HELP
Post questions like this to the SAS Support Communities.
If i want to run the do loop such that instead of i=1 to 12 i want to make it i=jan to dec. Is it possible to do this. If yes then how? Cz i have tried a lot but not happening. Plz do rply sir.
Yes, it is possible, but I would need more details to provide the code. Post your question to one of the SAS Support Communities, either the one for DATA step or the one for SAS/IML.
can u write that code plz i need it
Hi,
I am new to SAS and need help with properly using the DO loop. I am doing a simulation in SAS, and I'm using R to simulate the DATA and then bring it back to SAS to use specific functions.
Here is my code. My problem is I am finding it difficult using the DO loop to reiterate over the code as many times I would like while saving specific parameters every time it goes through a single iteration. Any help with this would help. Thanks!
data Meta_Results5;
do i= 1 to 3;
proc iml; /* using the SAS/IML environment to run the R code */
submit / R;
...
There are many problems with your program. Ask for help at the SAS/IML Support Community. If you plan on doing other simulations, you will find the book Simulating Data with SAS helpful.
My turn to ask a question:
I need to write the line below for each year from 1997 to 2010:
filename r1997 pipe ' R:\7za.exe e "R:\Data\registry1997.B.dat.gz" "registry1997.dat" -y -so '; data r1997; infile r1997; &i; run;
Is there a way to write it only once in a loop? I really appreciate any help.
That is what the macro language was developed for: to repeat SAS code multiple times when quantities like the names of files change for each iteration. See the example in the documentation for the %DO iterative statement. If you get stuck, post a question to the SAS Macro Support Community.
Hi!
I often follow your advises on sas community. Here I see you are posting about do loops. Today I was playing with some data and found out a problem. I have 5 data sets in txt format named roh_1.txt, roh_2.txt, roh_4.txt, roh_8.txt and roh_16.txt
I would like to make macro which will allow me to import those into SAS. I am familiar with infile option, but having issues with making macro. Of course I could rename files to be 1 to 5 but... Well I don't want to. Can you please give some hints.
Thanks
Please post your question and sample code to the SAS Support Communities.
Pingback: Do Loops, Probabilities and Simulations | Analytics
i have a question
there are some missing in data , i calculate -((xi-xj)^2)^0.5 for x2&x3 (contain complete data)
x1 x2 x3
1 3 2
2 1
3 2 1
4 1
how i can write this on sas?
It's not clear if you are asking about how to represent missing values or how to write the computation. The dot (.) is the missing value in SAS, so you can create the data set like this:
If you have a question about the computation, post it to a SAS Support Community
Rick ... you da man !!
I have a sas dataset as below.
fix var1 var2 var3
1 a b c
2 p q r
But I want to create a sas dataset as below
1 a
1 b
1 c
2 p
2 q
2 r
Anybody can help me that to write a sas code
This question is asked often on the SAS Support Communities. The helpful folks often suggest different approaches, such as PROC TRANSPOSE or the DATA step. This problem is known as reshaping data from "wide to long." I have written about how to use PROC TRANSPOSE to reshape data from wide to long.
data new;
input a_1 b_1$ c_1$ d_1$;
cards;
1 a b c
2 p q r
;
run;
proc sort data= new;
by a_1;
run;
proc transpose data= new out= new_1 (drop= _name_);
var b_1 c_1 d_1;
by a_1;
run;
Do you have a template for a do loop to do the following: I need to filter a large file by ID and then export the files into a folder, the files named with ID.
The basic template does not require a DO loop:
However, there are many reasons why you should NOT split data sets. For some of the reasons (and other techniques that split data sets), see "Split data into subsets."
Confusing.
data A;
y = 0;
do i = 1 to 5 by 0.5 while(y < 20);
y = i**2; /* values are 1, 2.25, 4, 6.25, ..., 16 */
output;
end;
run;
but the output reads:
y i
1 1
2,25 1,5
4 2
6,25 2,5
9 3
12,25 3,5
16 4
20,25 4,5
Since the numbers are correct, I assume that you are confused that the Y variable is printed first and the i variable is second?
The DATA step creates variables in the order that it sees them. The first statement sets y=0, so that that is why Y appears first in the data.
You can use PROC PRINT to print the data in any order:
proc print data=A; var i y; run;
You can also delete the "y=0;" statement and the i variable will appear first.
Hi,
No, what might confuse is:
/* values are 1, 2.25, 4, 6.25, ..., 16 */ in the comment.
The output data set contains the value 20.25 as well.
I see I used: , as comma instead of: . in my first comment.
Maybe that confused you :).
Ah, I see. Thanks. I have updated the comment in the blog post.
I use this type of code frequently for making changes in place on a large dataset in reverse, since the obs I'm normally updating are at the bottom and then I stop once the record has been found, but I can't get the code to work for just removing a record any thoughts?
data CRRG.CRRG;
do k = nobs to 1 by -1;
modify CRRG.CRRG nobs= nobs point=k;
if arrangement_key ='yyyyy' and as_of_date = '30Jun2016'd then do;
CUST_NUM = 'xxxxxx';
replace;
stop;
end;
end;
run;
I tried
data CRRG.CRRG;
do k = nobs to 1 by -1;
modify CRRG.CRRG nobs= nobs point=k;
if arrangement_key ='yyyy' and as_of_date = '30Jun2016'd then remove;
replace;
stop;
end;
run;
For suggestions about how to write efficient DATA step code, post your question and sample data to the SAS Support Community.
Question:
When using two or more Do Loops should they always be NESTED or can they OVERLAP?
DO /* Start of Do Loop One */
SAS Statements for Loop One ;
DO /* Start of Do Loop Two */
SAS Statements for Loop Two ;
END ; /* End of Do Loop Two */
More SAS Statements for Loop One ;
END ; /* End of Do Loop One */
/*******************************************************************************/
DO /* Start of Do Loop One */
SAS Statements for Loop One ;
DO /* Start of Do Loop Two */
SAS Statements for Loop Two ;
SAS Statements for Loop One ;
END ; /* End of Do Loop One */
More SAS Statements for Loop Two ;
END ; /* End of Do Loop Two */
If it is legal to overlap Do Loop structures, when would you need to do so?
Regards
The END statement always matches the closest DO staetment, so loops are always nested and never "overlap." This same fact is true in all computer languages that I am familiar with.
How can I print my name 10 times or more using do loop
Thanks for writing. It sounds like you are beginning to learn SAS programming. Congratulations. Since you will probably have many questions, I recommend that you post your questions to the SAS Support Communities. You'll be an expert in no time!
data yourname;
do i=1 to 10;
name="your name";
output;
end;
drop i;
run;
I have to use the value of a formula calculated in one row and then use the answer to calculate the value for the next row.
Foe eg: when the first instance is encountered it calculates the formalue and after that keeps re-using the pred value in the next few time - How can do it?
data starting_point_3;
set starting_point_2;
by key;
firstKey=first.key;
if firstKey then pred=(intercept+coeff_lag*pred_last_week);
run;
You can ask SAS programming questions like this at the SAS Support Communities.
Please i have ten tables created from
%n=1 %to &nobs
data test&n. ..........
So now i want to have all tables in one table,
I use proc append. it works but i some variables aren't found in the base.
So can i think i can use proc iml and do loops to create matrix and concatenate horizontally.
I don't know how proceed.
Can you help me please?
Post your question, example data, and the SAS code you are attempting at the SAS Support Communities.
%macro te();
%do n=1 %to 10;
data test&n. ( keep = id &idn. y1 yd yd1 - yd&p.);
set mytable (where=(id=&n.)) nobs=nobs;
N=nobs;
array un {*} yd yd1 - yd&p.;
do j=2 to dim (un);
un {j}= lag(un{j-1});
end;drop j;
run;
%end;
%macro te();
I get 10 datasets but i don't know how proceed to concatenate without lose variables because with proc append some variables aren't added.
Thanks,
i have a problem to solve this
A= {1 2 3 4 5}
B= {1 2 1}
step 1: A= {1 2 3 4 5}
B= {1 2 1}
step 2: A= {1 2 3 4 5}
B= {1 2 1}
step 3: A= {1 2 3 4 5}
B= {1 2 1}
please tell me the method & which loop i used to solve this.
if you get that method kindly reply soon & after that tell me if the length of A & B is increasing means we dont know the length then which method should i use?
You can ask SAS programming questions at the SAS Support Communities.
Hello, Rick,
I tried transforming the followings into a more efficient code using DO LOOP, but i failed. Can you please give me some guide for this?
data Input1;
set Input1;
if no= 2 then no= 2 + 0.1;
run;
data Input2;
set Input2;
if no= 2 then no= 2 + 0.2;
run;
data Input3;
set Input3;
if no= 2 then no= 2 + 0.3;
run;
I switched the above to the below.
DO i= 1 to 3;
data Input&i;
set Input&i;
if no= 2 then no= 2 + 0.1 * &i;
run;
End;
You need to use the macro DO loop: %DO i = 1 %TO 3; ... %END;
When you have SAS programming questions, please post them to the SAS Support Communitites.
Hello I would like to do a do loop over a list selected from a proc sql small data set. (in this case a 103 obs)
proc sql;
create table TERM_TBL_DIST as
select DISTINCT strm||'*'||acad_career as key, STRM, ACAD_CAREER
from &snapshotlib..PS_TERM_TBL
WHERE ACAD_YEAR BETWEEN "&year_four." and "&year.";
quit;
proc print data = TERM_TBL_DIST noobs n;run;
where my 'key' is the control and the data looks like:
ACAD_
key STRM CAREER
2153*UGRD 2153 UGRD
2153*VETM 2153 VETM
2155*BUSN 2155 BUSN
2155*GRAD 2155 GRAD
2155*IALC 2155 IALC
2155*MEDI 2155 MEDI
2155*PHAR 2155 PHAR
2155*UGRD 2155 UGRD
2155*VETM 2155 VETM
2157*BUSN 2157 BUSN
2157*GRAD 2157 GRAD
2157*IALC 2157 IALC
2157*MEDI 2157 MEDI
2157*PHAR 2157 PHAR
2157*UGRD 2157 UGRD
2157*VETM 2157 VETM
2160*UGRD 2160 UGRD
2163*BUSN 2163 BUSN
2163*GRAD 2163 GRAD
2163*IALC 2163 IALC
2163*MEDI 2163 MEDI
2163*PHAR 2163 PHAR
2163*UGRD 2163 UGRD
2163*VETM 2163 VETM
2165*BUSN 2165 BUSN
2165*GRAD 2165 GRAD
I notice a part in the above information that made it looks like any random txt can make up the list of control var, but can I auto populate this list or do I have to prerun my list and stuff the data into a written out list in my code? If this is possible can someone show me how to get my data in to this list? TIA. -KJ
PS If there is a better way to do this I am fine with that too. I just need to control a loop with a generated key.
Thanks for writing. The best way to discuss and resolve this issue is to post it to the SAS Support Community for Base SAS Programming.
Hi,
How can i send sms text on phone using sas..please help
You can ask programming questions at the SAS Support Communities. For this question, you can start by looking at the article "How to send a text message with SAS."
Pingback: LEAVE and CONTINUE: Two ways to control the flow in a SAS DO loop - The DO Loop
Hi,
Suppose I have
PROC MEANS data=s100 NOPRINT;
VAR s100;
CLASS school;
OUTPUT OUT=s100(drop = _type_ _freq_) SUM=S100;
RUN;
data S100;
set S100;
population=100;
if school=' ' THEN school='999999';
RUN;
And I want to loop from S100 to S200. How?
Hi
I have employee code, date, totalhours(time format), weekno, now i want is to calculate sum of hours per week per person
i.e in sql sum(hours) group by(week_no) ,
please help.
regards,
Sir , why we use output statement before end statement in do looping?
The best way to learn is by doing. I suggest you run the program here and look at the resulting data set. Then delete the OUTPUT statement, run it again, and look at the result. If you have further questions, ask at the SAS Support Communities.
Hello,
How could I iterate through all obs per obs in a SAS dataset? Example, I have a dataset with five obs. I'd like to take the first one and compare that one against all next observations. Then take the second obs, and compare it against all others, then the third compare against all, etc..
I guess from a C stand point it'd be somehting like this:
for (i=0;i<5;i++)
{
for (j=0; j <5; j++)
{
if (pin[i] == pin[j])
{
aux += 1;
}
}
}
You can ask questions like this at the SAS Support Communities. Be sure to provide sample data in the form of a DATA step. In general, the SAS DATA step processes one observation at a time, so solutions to problems like this often involve transposing the data and using arrays in the DATA step, or using a procedure such as PROC SQL or PROC IML.
Hi ,
Please find the below SAS code, when I execute the program the value of n in the title is 6. It would be great if I get a clarification for the same
%macro namelst(name,number);
%global n;
%do n=1 %to &number;
&name&n
%end;
%mend namelst;
data sample;
dept1=1;
dept2=2;
dept3=3;
dept4=4;
dept5=5;
run;
proc print;
var %namelst(dept,5);
title "Quarterly Report for &n";
run;
Thanks for writing. Yes, the value of the counter at the end of the loop is one more than the upper limit of the loop. (This is true in any programming language.) That is because when the counter equals the upper limit, the body of the loop executes. At the end of the body, the control passes to the top of the loop, which increments the counter and checks the upper limit. Because the counter is greater than the upper limit, the body does not execute and the control passes to the next executable statement after the body of the loop. The following statements show a DATA step example:
Hi Rick,
I am running a simulation that outputs multiples datasets. I combine them for the output (data combine / view=combine;).
Currently, I am entering the data sets in manually. (set MM.RESULT_1 MM.RESULT_2 MM.RESULT_3......)
Is there a do loop that could automatically fill in the number at the end (MM.RESULT_" ")
Thank you in advance
Thanks for writing. The most efficient way to generate samples in a simulation is shown in the article "Simulation in SAS: The slow way or the BY way." For more tips, see "Ten Tips for Simulating Data with SAS," especially tips 6-8. I've also written dozens of blogs posts about Monte Carlo simulation, such as this regression example.
hi
i have input like
1
1 1
1 1 1
1 1 1 1
1 1 1 1 1
;
and i need to get the output like
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
I have a dataset given by the following script:
data A (drop = Date_1 fmt1 Date_2 fmt2);
input CustomerID : $1.
Address : $1.
<snip>
run;
I need to know for each CustomerID, how many other customers were at the same address before the customer transacted. Can I do this with a loop? The answer needs to appear as below:
<snip>
You can post SAS programming questions to the SAS Support Communities.
Hi Rick,
I am trying to create a loop using decimals, but getting error. Any help would be appreciated.
While executing %print I am getting error and the loops do not evaluate.
%macro print;
%do i= 0.5 %to 0.8 %by 0.1;
%put &i.;
%end;
%mend;
%print;
1. Please ask questions and post code on the SAS Support Communities.
2. Here is a link to the documentation for the %DO iterative macro statement
3. The documentation states that the start, stop, and increment values must be integers.
How to print triangle by using do loop statement
*
**
***
*****
*******
Pingback: Little known secrets of DO-loops with index variables - SAS Users
data new;
input fix var1$ var2$ var3$;;
cards;
1 a b c
2 p q r
;
run;
%macro nw;
data new2;
set new;
%do i=1 %to 3;
lt&i=fix || var&i;
drop var&i fix;
%end;
run;
%mend nw;
%nw;
Personally, I'd use arrays and a DO loop instead of a macro loop:
Something I recently learned which I long been wondering about. Using loops to split a long variable into multiple variables, splitting along spaces as to not break up any words up.
array vars [*] $200 var1-var10; *new variables to be created;
cnt=0;
do until(missing(longvar));
cnt+1;
do i=200 by -1 until(missing(char(longvar,i))); *finds the position of the first blank starting from the end;
end;
vars[_cnt]=left(substr(longvar,1,i-1)); *assign everything before the space to a new variable;
longvar=substr(longvar,i+1); *remove from the long variable the portion assigned to the new variable;
end;
Or you can use the COUNTW function to get the number of words and use the SCAN function to iterate over the words in each line. See "Break a sentence into words in SAS."
thanks for looking at this. Where I have vars[_cnt], should be vars[cnt]. I agree with you, but the goal here was to split up a long series of words into multiple variables having a shorter series of words. Your idea is for creating a variable for each word in the original text. Either way, no words get broken up.
I have a data set with records of city-wise information. In SAS Data step, I want to export citywise data from the SAS data set with different citywise excel sheets.