BookmarkSubscribeRSS Feed
vThanu
Calcite | Level 5

data have;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 3 5
;

 

I want to find out the last non-missing value?

Generally if we use coalesce function we get first non-missing value right.

I am looking for last non-missing value.... in the same sequencial order (a,b.c.d...) or (A--D);

 

Thanks in advance

9 REPLIES 9
DanielLangley
Quartz | Level 8
data have;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 3 5
;
run;

data want(drop = i);
set have;
array nums[*] A--D;
do i = dim(nums) to 1 by -1 until (i=1 or vvalue(nums[i]) ne . );
	LastNonMissing = nums[i];
end;
run;

LastNonMissing will be missing if the entire row is missing.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

As an alternative to the array method:

data have;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 3 5
;
run;

data want;
  set have;
  lastmissing=scan(catx(',',of a--d),-1,',');
run;
mansour_ib_sas
Pyrite | Level 9
data want;
set have;
NM= coalesce(d,c,b,a);
run;
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Yes, the coalesce is a good idea, only problem is you can't do lists in reverse.  It would be great to do:

  lastmissing=coalesce(of d--a);

But we can't as that's not the order of the variables.  So needing to put a lot of variables in the line could get long winded.  

 

DanielLangley
Quartz | Level 8

Hi @RW9 This is a really elegant solution however sometimes numbers contain commas which could throw your results off.

 

 

data have;
format a b c d comma9.;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 3 5
4 . 3000 .
;
run;

data want(drop = i);
set have;
array nums[*] A--D;
do i = dim(nums) to 1 by -1 until (i=1 or nums[i] ne . ); *Modified to get rid of vvalue;
	LastNonMissing = nums[i];
end;
lastmissing=scan(catx(',',of a--d),-1,','); *from RW9;
NM= coalesce(d,c,b,a); * from mansour_ib_sas;
run;

 

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

True (although whether actual numbers (rather than formatted) can contain commas is a different discussion Smiley Happy ) and hadn't though about that.  Just replace the comma usage:

data want;
  set have;
  lastmissing=scan(catx('|',of a--d),-1,'|');
run;

A bar (pipe) for instance.

novinosrin
Tourmaline | Level 20

Hi @vThanu 

 

Thank you for the interesting question. 

 

The solutions you received so far:

 

1. Loop aka linear search

2. Colaesce ( problem: what if you have numerous variables to reverse the list, this would involve loading the list in a macro var in a reverse order

3. scan ( didn;t work as it didn;t produce 4 6 5 5 as the wanted result but I think this is a slick approach regardless)

 

One easy approach in my opinion is

 

data have;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 3 5
;
run;

data want;
set have;
temp=compress(cats(of a--d),'.');
lastnonmissing=char(temp,length(temp));
drop temp;
run;

This handles the variable list conveniently, stripping of '.' from the last and extracting the last one.

 

Results:

 

a b c d lastnonmissing 
1 2 . 4 4 
4 . 3 6 6 
2 3 5 . 5 
. 2 3 5 5 

 

mansour_ib_sas
Pyrite | Level 9

Another solution is possible:

data test;
input a b c d;
cards;
1 2 . 4
4 . 3 6
2 3 5 .
. 2 . .
;
run;

proc contents noprint  data=test out=test1;run;

proc sql noprint ;
select name into : col separated by ' ' from test1 order by varnum desc;
quit;

 
data test1(drop=i);
set test;
array nums &col.;
do i=dim(nums) to 1 by -1;
if nums(i) ^= . then do;
 lnm=nums(i);
output;
leave;
end;
end;
run;

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
  • 9 replies
  • 3303 views
  • 1 like
  • 5 in conversation