BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
PrudhviB
Obsidian | Level 7

Hi Community,

I am trying to create a new Column with custom values from existing records in the data set. I am finding it difficult when I want to combine date and a text format as a column. 

I have included the sample data for the reference, any help is much appreciated. 

 

my approach:

I used Case function to created tags (under column want)  was unsuccessful for wk of May2nd on wards. 

(CASE
WHEN t1.week_end BETWEEN '01JUN2019'd AND '30JUN2019'd THEN 'LegacySoftW'
WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'NO_legacySoft'
ELSE
END)

 

My data start from june 3rd 2019 and it goes on, ideally i want to have a column generated using the date field to create a tag under the new column (Column_want) with the format "wk of month(week_start) day(week_start)".

 

hope this is clear. 

 

Product_ID Week_start Week_end Sales Column_want(Tag)
500024 3-Jun-19 7-Jun-19 15 LegacySoftw
500026 10-Jun-19 14-Jun-19 20 LegacySoftw
500028 17-Jun-19 21-Jun-19 2 LegacySoftw
500030 24-Jun-19 28-Jun-19 65 LegacySoftw
500031 24-May-21 28-May-19 0  
500032 31-May-21 4-Jun-21 5  
500034 7-Jun-21 11-Jun-21 7 No _LegacySoft
500036 14-Jun-21 18-Jun-21 54 No _LegacySoft
500038 21-Jun-21 25-Jun-21 5 No _LegacySoft
500040 28-Jun-21 2-Jul-21 32 No _LegacySoft
500042 2-May-22 6-May-22 54 Wk of May 2nd
500044 9-May-22 13-May-22 58 Wk of May 9th
500046 16-May-22 20-May-22 84 Wk of May 16th
500048 23-May-22 27-May-22 6 Wk of May 23th
500050 30-May-22 3-Jun-22 87 Wk of May 30th 
500052 6-Jun-22 10-Jun-22 58 Wk of June 6th
1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Below code getting you very close to what you're asking for.

You will have to re-assess your condition WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'No_legacySoft'   because based on your sample data the end date should actually be '02Jul2021'd

data have;
  infile datalines truncover dsd dlm='|';
  input
    Product_ID    
    Week_start:date.
    Week_end:date.
    Sales 
    Column_Want :$40.
    ;
  format week_start week_end date9.;
  datalines;

500024|3-Jun-19|7-Jun-19|15|LegacySoftw
500026|10-Jun-19|14-Jun-19|20|LegacySoftw
500028|17-Jun-19|21-Jun-19|2|LegacySoftw
500030|24-Jun-19|28-Jun-19|65|LegacySoftw
500031|24-May-21|28-May-19|0| 
500032|31-May-21|4-Jun-21|5| 
500034|7-Jun-21|11-Jun-21|7|No _LegacySoft
500036|14-Jun-21|18-Jun-21|54|No _LegacySoft
500038|21-Jun-21|25-Jun-21|5|No _LegacySoft
500040|28-Jun-21|2-Jul-21|32|No _LegacySoft
500042|2-May-22|6-May-22|54|Wk of May 2nd
500044|9-May-22|13-May-22|58|Wk of May 9th
500046|16-May-22|20-May-22|84|Wk of May 16th
500048|23-May-22|27-May-22|6|Wk of May 23th
500050|30-May-22|3-Jun-22|87|Wk of May 30th 
500052|6-Jun-22|10-Jun-22|58|Wk of June 6th
;

proc sql;
/*  create table want as*/
  select
    *,
    CASE
      WHEN t1.week_end BETWEEN '01JUN2019'd AND '30JUN2019'd THEN 'LegacySoftW'
      WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'No_legacySoft'
      when t1.week_end > '30JUN2021'd then catx(' ','Wk of'
                                          ,put(Week_start,monname.), put(Week_start,day.))
      ELSE ' '
      END as Column_Derived
  from have t1
  ;
quit;

Patrick_0-1655498353619.png

 

View solution in original post

5 REPLIES 5
Patrick
Opal | Level 21

Your else case needs to define the blank and you also need to define the column name for storing the values.

CASE
WHEN t1.week_end BETWEEN '01JUN2019'd AND '30JUN2019'd THEN 'LegacySoftW'
WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'NO_legacySoft'
ELSE ' '
END as want

Given your sample data: Would that be above logic and then everything after June 30, 2021 generates these week strings?

 

 

PrudhviB
Obsidian | Level 7

@Patrick that is correct, anything after June 30th 2021 I want it to create that format of sting with the week start date. 

Patrick
Opal | Level 21

Below code getting you very close to what you're asking for.

You will have to re-assess your condition WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'No_legacySoft'   because based on your sample data the end date should actually be '02Jul2021'd

data have;
  infile datalines truncover dsd dlm='|';
  input
    Product_ID    
    Week_start:date.
    Week_end:date.
    Sales 
    Column_Want :$40.
    ;
  format week_start week_end date9.;
  datalines;

500024|3-Jun-19|7-Jun-19|15|LegacySoftw
500026|10-Jun-19|14-Jun-19|20|LegacySoftw
500028|17-Jun-19|21-Jun-19|2|LegacySoftw
500030|24-Jun-19|28-Jun-19|65|LegacySoftw
500031|24-May-21|28-May-19|0| 
500032|31-May-21|4-Jun-21|5| 
500034|7-Jun-21|11-Jun-21|7|No _LegacySoft
500036|14-Jun-21|18-Jun-21|54|No _LegacySoft
500038|21-Jun-21|25-Jun-21|5|No _LegacySoft
500040|28-Jun-21|2-Jul-21|32|No _LegacySoft
500042|2-May-22|6-May-22|54|Wk of May 2nd
500044|9-May-22|13-May-22|58|Wk of May 9th
500046|16-May-22|20-May-22|84|Wk of May 16th
500048|23-May-22|27-May-22|6|Wk of May 23th
500050|30-May-22|3-Jun-22|87|Wk of May 30th 
500052|6-Jun-22|10-Jun-22|58|Wk of June 6th
;

proc sql;
/*  create table want as*/
  select
    *,
    CASE
      WHEN t1.week_end BETWEEN '01JUN2019'd AND '30JUN2019'd THEN 'LegacySoftW'
      WHEN t1.week_end BETWEEN '01JUN2021'd AND '30JUN2021'd THEN 'No_legacySoft'
      when t1.week_end > '30JUN2021'd then catx(' ','Wk of'
                                          ,put(Week_start,monname.), put(Week_start,day.))
      ELSE ' '
      END as Column_Derived
  from have t1
  ;
quit;

Patrick_0-1655498353619.png

 

Reeza
Super User

I would first create a format for the ordinal part of the day.

data ordinal_format;
	length label $8.;
  do number=1 to 31;
    numstring = put(number, 16. -l);
    if prxmatch('/(?<!1)1\s*$/',numstring) then ending='st';
    else if prxmatch('/(?<!1)2\s*$/',numstring) then ending='nd';
    else if prxmatch('/(?<!1)3\s*$/',numstring) then ending='rd';
    else ending = 'th';
    ordstring =catt(numstring, ending);

	  start=number;
	  label=ordstring;
	  fmtname="ordinal_fmt";
	  type="N";
	  output;
  end;


	keep start label fmtname type;
run;

proc format cntlin=ordinal_format;
run;

Then modify your CASE statement as follows:

 

else when t1.week_end > '30June2021'd then 
  cat('Wk of ', put(t1.weekend, monname.), ' ', put(day(t1.weekend), ordinal_fmt.))

 EDIT: months can have 31 day so updated format to have 31 days.

PrudhviB
Obsidian | Level 7

Thank you @Reeza this one also worked. 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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
  • 5 replies
  • 878 views
  • 2 likes
  • 3 in conversation