I want to create a data set where I only want to keep 5 specific dates.
So my &date is 31mar2020 and &enddate is 31mar2025 and I only want to keep 31mar every year until 2025.
With my code below it creates dates for everyday up to 31mar2025 and thats to much so I only want to keep 5 specific dates.
How can i do that?
Thank you
DATA LOOP;FORMAT ROLL_BASE_DT DATE9.;DO ROLL_BASE_DT =&DATE TO &ENDdate;OUTPUT;END;RUN;
enter code here
enter code here
You can use commas in the DO statement to list multiple values.
do date='31mar2021'd,'31mar2022'd,'31mar2023'd,'31mar2024'd,'31mar2025'd;
...
end;
You could loop over the YEAR value instead.
do year=2021 to 2025;
date=mdy(3,31,year);
...
end;
You could use INTNX() to increment the date by YEAR. You can use INTCK() to figure out how many times to run the loop.
do index=0 to intck('year',&DATE,&ENDdate);
date=intnx('year',&date,index,'s');
...
end;
If it's just the 5 dates you want, you could use the cards input (I know of it but have never used it personally).
Alternatively, rather than using a loop just set the values individually with the output keyword after each time you set the value. That should do it.
Related
I need to use the day and month variables to create a date variable using the array function. For example, let's say the year is 2022, which needs to be included in the date.
I tried the following codes, but it doesn't seem to work. SAS gave me a number but not sure that's the correct date. Thanks for your help.
array day{1} day_1;
array month{1} month_1;
array date{1} date_1;
do i=1 to dim(day);
date{i}=MDY(month{i},day{i},2022);
end;
format date_1 mmyydd10.;
run;
Your posted code does not have a DATA statement telling SAS what dataset you want to create. Nor anyway to find the existing DAY_1 or MONTH_1 variables. If the variables are in an existing SAS dataset then add a SET statement.
If there is only one DAY variable and one MONTH variable there is no need for the ARRAY or the DO loop.
data want;
set have;
date_1=MDY(month_1,day_1,2022);
format date_1 mmyydd10.;
run;
If you do have multiple variables then include them in the arrays and the FORMAT statement.
data want;
set have;
array day day_1-day_3
array month month_1-month_3;
array date date_1-date_3;
do i=1 to dim(day);
date{i}=MDY(month{i},day{i},2022);
end;
format date_1-date_3 mmyydd10.;
drop i;
run;
I'm asked to make a view for a bunch of columns coming from a bunch of different tables. You See the OTHours column needs to be created by taking the Workhours data and seeing if it goes over 40 hours. If it does then I take that number and put it into the OTHours column.
Also If there is a holiday in that week that means anything over 32 hours is considered overtime. Here's some sample data How would I do this without using any variables to store the overtime hours since it must be done using a conditional and or some function?
Try to use CASE statement like this:
select
case
when WorkHours>40 or (WorkHours>32 and HolHours) then WorkHours
else 0
end as OTHours
I am trying to only pull lunch times in an array if they are over an hour long and display the full value of that time.
I've tried to use an if statement to wrap the entire code and increment if false by one. I've been searching forms trying to see what I am doing wrong but not able to find anything. I have one functioning formula that will pull all break times and display time and dates but does not work when I try to use it to find specifics ones.
Two cells that are working:
Date it happened: {=IFERROR(INDEX(Time,SMALL(IF(Reason=$K7,ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:K7))),"")}
Value of Duration: {=IFERROR(Duration(Time,SMALL(IF(Reason=$K7,ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:K7))),"")}
The formula I am trying:
{=IF(INDEX(Duration,SMALL(IF(Reason=$K7,ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:K7)))>=TIME(1,0,0),IFERROR(INDEX(Duration,SMALL(IF(Reason=$K7,ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:K7))),""),IFERROR(INDEX(Duration,SMALL(IF(Reason=$K7,ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:L7))),""))}
That formula does ignore the times that are under an hour however it pulls the same data twice. For Example the first duration formula displays the following:
1:11:46 0:59:28 1:11:51 1:10:59
The second one shows:
1:11:46 1:11:51 1:11:51 1:10:59
My ultimate goal is to have it look up a name and then for breaks/lunches but for right now I just want to to look up the lunch times. I would like it to make the output of 1:11:46 1:11:51 1:10:59 . Any thoughts?
=IFERROR(INDEX(Duration,SMALL(IF((Reason=$K7)*(Duration>=TIME(1,0,0)),ROW(Duration)-MIN(ROW(Duration))+1),COLUMNS($K$7:K7))),"")
^ That fixed it
I have a pretty complex SQL query that is pulling data from a our database for a particular month #month.
The month is based on our internal month-numbering system, so at the beginning of the code, we define the month number we would like to use.
I have now been informed that we need this code running for the previous 12 months, is there an easy way to convert the whole code into an EXEC statement so I can loop through the different values of the #month variable?
I've done this before for simple code, but this one has lots of string-based criteria, which would need to be manually edited to accommodate all the inverted commas (').
Thanks in advance.
Put your query inside a store procedure with #month param in input, then call you procedure 12 time:
s_procName 1
s_procName 2
s_procName 3
.....
I have a range of weekly variables describing a person's "status" (from week 1, 2010 to 2012 week 17).
The variables are given by:
y_1001, y_1002,...y1052, y1101, y1102,......y_1217
I define the period of variables like this:
%let period = y_1001-1052 y_1101-y1148;
I also have a treatment period given as a start date and an end date. My challenge is to find the status given by the y_ variables in the week after the person stops the treatment.
I am not too familiar with SAS, but my idea was to "pick" the correct y_ variable based on a week counter, say by counting the number of weeks since the beginning of the period (week 1 in 2010) and until the date where the treatment ends.
I get the weeks until end of treatment like this
week_count = 1 + intck( 'week.2', '1JAN2010'd, end_treatment_date, 'd');
But how can I retrieve the corresponding y_ variable based on this count?
After fruitless search on how to loop over the period variables and pick the number corresponding to the week_count variable for each person, I thought about going a different way... say something like this.
array weeks(*) .
do i = 1 to dim(weeks) by 1;
if week_count = i then end_status = y_10&i;
end
...but with modifications to take into account that there is a mismatch between the dimension of the array and the number of weeks and years.
But then my challenge is to make the following part work...
if week_count = i then end_status = y_10&i;
How can I make SAS pick the right y_ variable based on the loop index? This seems like a really simple problem, but somehow I have not managed to find a solution. Is there no way to use the variable "i" as input in defining the correct y_ variable?
Would really appreciate if somebody could throw some hints.
I think you want:
if week_count = i then end_status = weeks{i};
VVALUEX is a little known function in SAS which can help you to extract a value from a SAS variable name. Here your problem is to construct the SAS variable name given the number of weeks from the 1st Jan to the end of treatment. You can avoid using a DO LOOP for every observation by using the ideas in the example below -
data _null_;
end_treatment_date = "09FEB2010"d;
y_1007 = 'D';
status = vvaluex(compress("y_" || substr(strip(year(end_treatment_date)), 3, 2) || put(1 + intck("week.2", "01JAN2010"d, end_treatment_date), z2.)));
put status;
run;
The variable name is constructed as follows - initally you take the string "y_" and then append the last two digits of the year followed by the week using similar logic to your variable week_count as before. You get the variable you want, and then apply VVALUEX to get the value. Running the DO LOOP for every observation can be inefficient if you have millions of them.