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

I have three date columns as shown in the 'have' table below. I would like to sort them and create a type variable that is the name of the date column (see the 'want' table). 

In some cases, two dates may be equal in which case, they will only be counted as one date when sorting them, but both names should be included in the 'type' (see row 2 of 'want'). 

I came up with a very clunky way to do this with if/then statements, but I am wondering if there is a better way. 

 

data have;
   input A :yymmdd10. B :yymmdd10. C :yymmdd10. ; 
   format A B C yymmdd10.;
   infile datalines delimiter=','; 
   datalines;                      
2019/01/01, 2018/03/13, . 
2017/02/02, . , 2017/02/02
2018/11/18, 2018/08/01, 2021/07/02
;
run;


data want; 
	input date1 :yymmdd10. date2 :yymmdd10. date3 :yymmdd10. type1 $ type2 $ type3 $;
	format date1 date2 date3 yymmdd10.; 
	infile datalines delimiter=',';
	datalines; 
2018/03/13, 2019/01/01, ., B, A, . 
2017/2/2, . , . , A/B, . , .
2018/08/01, 2018/11/18, 2021/07/02, B, A, C
;
run;
	
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Your second output seems wrong. 

The original variables where A and C , not A and B.

 

data have;
  input (A B C) (:yymmdd.);
  format A B C yymmdd10.;
datalines;                      
2019/01/01  2018/03/13  . 
2017/02/02  .           2017/02/02
2018/11/18  2018/08/01  2021/07/02
;


data expect; 
  input (date1-date3) (:yymmdd.) (type1-type3) (:$100.);
  format date1-date3 yymmdd10.; 
datalines; 
2018/03/13  2019/01/01  .           B    A  . 
2017/2/2    .           .           A/B  .  .
2018/08/01  2018/11/18  2021/07/02  B    A  C
;

data step1;
  row+1;
  set have;
run;

proc transpose data=step1 out=step2 ;
  by row;
  var a b c ;
run;

proc sort data=step2;
  by row col1;
run;

data want;
  set step2;
  by row col1;
  where not missing(col1);
  array date [3];
  array type [3] $100 ;
  retain date: type: ;
  format date: yymmdd10.;
  if first.row then call missing(of index date[*] type[*]);
  index + first.col1;
  date[index]=col1;
  type[index]=catx('/',type[index],_name_);
  if last.row then output;
  keep row date: type:;
run;

proc print data=want;
run;
 
proc compare data=want compare=expect;
run;
The COMPARE Procedure
Comparison of WORK.WANT with WORK.EXPECT
(Method=EXACT)

Value Comparison Results for Variables

__________________________________________________________
           ||  Base Value           Compare Value
       Obs ||  type1                 type1
 ________  ||  ___________________+  ___________________+
           ||
        2  ||  A/C                   A/B
__________________________________________________________

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

Your second output seems wrong. 

The original variables where A and C , not A and B.

 

data have;
  input (A B C) (:yymmdd.);
  format A B C yymmdd10.;
datalines;                      
2019/01/01  2018/03/13  . 
2017/02/02  .           2017/02/02
2018/11/18  2018/08/01  2021/07/02
;


data expect; 
  input (date1-date3) (:yymmdd.) (type1-type3) (:$100.);
  format date1-date3 yymmdd10.; 
datalines; 
2018/03/13  2019/01/01  .           B    A  . 
2017/2/2    .           .           A/B  .  .
2018/08/01  2018/11/18  2021/07/02  B    A  C
;

data step1;
  row+1;
  set have;
run;

proc transpose data=step1 out=step2 ;
  by row;
  var a b c ;
run;

proc sort data=step2;
  by row col1;
run;

data want;
  set step2;
  by row col1;
  where not missing(col1);
  array date [3];
  array type [3] $100 ;
  retain date: type: ;
  format date: yymmdd10.;
  if first.row then call missing(of index date[*] type[*]);
  index + first.col1;
  date[index]=col1;
  type[index]=catx('/',type[index],_name_);
  if last.row then output;
  keep row date: type:;
run;

proc print data=want;
run;
 
proc compare data=want compare=expect;
run;
The COMPARE Procedure
Comparison of WORK.WANT with WORK.EXPECT
(Method=EXACT)

Value Comparison Results for Variables

__________________________________________________________
           ||  Base Value           Compare Value
       Obs ||  type1                 type1
 ________  ||  ___________________+  ___________________+
           ||
        2  ||  A/C                   A/B
__________________________________________________________

kz_
Quartz | Level 8 kz_
Quartz | Level 8
Thank you! That's exactly what I needed.
data_null__
Jade | Level 19

Here is a method that is the same but different. 😀

 

data have;
   infile datalines delimiter=','; 
   id + 1;
   input A :yymmdd10. B :yymmdd10. C :yymmdd10. ; 
   format A B C yymmdd10.;
   datalines;                      
2019/01/01, 2018/03/13, . 
2017/02/02, . , 2017/02/02
2018/11/18, 2018/08/01, 2021/07/02
;
run;
proc print;
   run;
proc transpose data=have out=tall(where=(not missing(col1)));
   by id;
   run;
proc sort;
   by id col1;
   run;
data tall2;
   length type $8;
   do until(last.col1);
      set tall; by id col1;
      date = col1;
      type = catx('/',type,_name_);
      end;
   format date yymmdd10.;
   run;
proc print;
   run;
proc summary data=tall2 nway;
   class id;
   output out=want(drop=_type_) idgroup(out[3](date type)=);
   run;
proc print;
   run;

Capture.PNG

 

kz_
Quartz | Level 8 kz_
Quartz | Level 8
Thank you! This works too.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 705 views
  • 1 like
  • 3 in conversation