BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
jksthomas
Calcite | Level 5

Below is my data in column SUBJ, B and VALUE. I need MINIM column with the min(VALUE) compared to previous observations for same subject. Can Any one help?

 

SUBJ	SEQ	VALUE	MINIM	  This is how MIN value is calculated
1004	1	35.58	-	 - There is no obs previous and should appear blank
1004	2	32.69	35.58	 - Only one obs available prior so 35.58 is min
1004	3	26.15	32.69	 - Compared to obs 1, 2 value of 32.69 is min
1004	4	21.77	26.15	 - Compared to obs 1, 2 and 3 value of 26.15 is min
1004	5	19.47	21.77	 - Compared to 1, 2,3 and 4 value of 21.77 is min
1004	6	19.52	19.47	 - Compared to 1, 2,3,4 and 5 value of 19.47 is min
1004	7	13.71	19.47	 - Compared to 1, 2,3,4,5 and 6 for this subject value of 19.47 is min
1004	8	13.7	13.71	
1004	9	13.97	13.7	
1004	10	24.28   13.7
1005	1	22.57	-	 - There is no previous obs for this subject and should appear blank
1005	2	10.21	22.57	 - Only one row available previous so 22.57 is min
1005	3	10.35	10.21	 - Compared to 1, 2 value of 10.21 is min
1005	4	10.35	10.21	 - Compared to 1, 2 and 3 value of 10.21 is min
1005	5	10.35	10.21	 - Compared to 1, 2,3 and 4 for this subject value of 21.77 is minimum
1005	6	9.76	10.21

 

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hi @jksthomas and welcome to the SAS Support Communities!

 

Here's another DATA step solution:

data want;
do until(last.subj);
  set have;
  by subj seq;
  output;
  minim=min(minim,value);
end;
run;

View solution in original post

9 REPLIES 9
novinosrin
Tourmaline | Level 20

data have;
input SUBJ	SEQ	VALUE; *	MINIM	  This is how MIN value is calculated;
cards;
1004	1	35.58	-	 - There is no obs previous and should appear blank
1004	2	32.69	35.58	 - Only one obs available prior so 35.58 is min
1004	3	26.15	32.69	 - Compared to obs 1, 2 value of 32.69 is min
1004	4	21.77	26.15	 - Compared to obs 1, 2 and 3 value of 26.15 is min
1004	5	19.47	21.77	 - Compared to 1, 2,3 and 4 value of 21.77 is min
1004	6	19.52	19.47	 - Compared to 1, 2,3,4 and 5 value of 19.47 is min
1004	7	13.71	19.47	 - Compared to 1, 2,3,4,5 and 6 for this subject value of 19.47 is min
1004	8	13.7	13.71	
1004	9	13.97	13.7	
1004	10	24.28   13.7
1005	1	22.57	-	 - There is no previous obs for this subject and should appear blank
1005	2	10.21	22.57	 - Only one row available previous so 22.57 is min
1005	3	10.35	10.21	 - Compared to 1, 2 value of 10.21 is min
1005	4	10.35	10.21	 - Compared to 1, 2 and 3 value of 10.21 is min
1005	5	10.35	10.21	 - Compared to 1, 2,3 and 4 for this subject value of 21.77 is minimum
1005	6	9.76	10.21
;

data want;
 do _n_=1 by 1 until(last.subj);
  set have;
  by subj;
  array t(99999) _temporary_;
  if _n_>1 then min=min(of t(*));
  t(_n_)=value;
  output;
 end;
 call missing(of t(*));
run;
novinosrin
Tourmaline | Level 20

And if you want a SQL solution

 


data have;
input SUBJ	SEQ	VALUE; *	MINIM	  This is how MIN value is calculated;
cards;
1004	1	35.58	-	 - There is no obs previous and should appear blank
1004	2	32.69	35.58	 - Only one obs available prior so 35.58 is min
1004	3	26.15	32.69	 - Compared to obs 1, 2 value of 32.69 is min
1004	4	21.77	26.15	 - Compared to obs 1, 2 and 3 value of 26.15 is min
1004	5	19.47	21.77	 - Compared to 1, 2,3 and 4 value of 21.77 is min
1004	6	19.52	19.47	 - Compared to 1, 2,3,4 and 5 value of 19.47 is min
1004	7	13.71	19.47	 - Compared to 1, 2,3,4,5 and 6 for this subject value of 19.47 is min
1004	8	13.7	13.71	
1004	9	13.97	13.7	
1004	10	24.28   13.7
1005	1	22.57	-	 - There is no previous obs for this subject and should appear blank
1005	2	10.21	22.57	 - Only one row available previous so 22.57 is min
1005	3	10.35	10.21	 - Compared to 1, 2 value of 10.21 is min
1005	4	10.35	10.21	 - Compared to 1, 2 and 3 value of 10.21 is min
1005	5	10.35	10.21	 - Compared to 1, 2,3 and 4 for this subject value of 21.77 is minimum
1005	6	9.76	10.21
;

proc sql;
create table want as
select a.subj,a.seq,a.value,min(b.value) as min
from have a left join have b
on a.subj=b.subj
and b.seq<a.seq
group by a.subj,a.seq,a.value
order by a.subj,a.seq;
quit;
FreelanceReinh
Jade | Level 19

Hi @jksthomas and welcome to the SAS Support Communities!

 

Here's another DATA step solution:

data want;
do until(last.subj);
  set have;
  by subj seq;
  output;
  minim=min(minim,value);
end;
run;
novinosrin
Tourmaline | Level 20

Indeed more efficient and tactfully observed(the values), makes me realise my lethargy. Need to change my coffee brand big time. Kudos!

jksthomas
Calcite | Level 5

@novinosrin wrote:

Indeed more efficient and tactfully observed(the values), makes me realise my lethargy. Need to change my coffee brand big time. Kudos!


@novinosrin @FreelanceReinh Both of your prog worked well. Thanks a lot.

jksthomas
Calcite | Level 5

@jksthomas wrote:

@novinosrin wrote:

Indeed more efficient and tactfully observed(the values), makes me realise my lethargy. Need to change my coffee brand big time. Kudos!


@novinosrin @FreelanceReinh Both of your prog worked well. Thanks a lot.


One more question: Can I get one more additonal row to display which seq from the subj is taken as minim?

FreelanceReinh
Jade | Level 19

@jksthomas wrote:


One more question: Can I get one more additonal row to display which seq from the subj is taken as minim?


Sure (assuming you mean: additional column, i.e. variable😞

data want;
do until(last.subj);
  set have;
  by subj seq;
  output;
  if value<minim | first.subj then do;
    minim=value;
    seq_minim=seq;
  end;
end;
run;

In the case of tied minimum values, e.g., if in your sample data the observation with SUBJ=1005, SEQ=4 had VALUE=10.21 (instead of 10.35), the above code would store the first SEQ with a VALUE of 10.21 in SEQ_MINIM, i.e., SEQ_MINIM=2 for the last four observations. By replacing the "<" sign in the IF condition with "<=" you could obtain the last SEQ instead, i.e., SEQ_MINIM=4 in the last two observations (and, of course, still SEQ_MINIM=2 in the two preceding observations).

jksthomas
Calcite | Level 5

hi,

Thanks again for you help

Sorry i mean to say new variable.

Prog works fine from 3rd row, however, for the second row SEQ_MINIM is blank. Is there a way to display seq = 1 .

 

SUBJ	VALUE	SEQ	MINIM	SEQ_MINIM
1001003	22.57	1		
1001003	10.21	2	22.57	
1001003	10.35	3	10.21	2
1001003	10.35	4	10.21	2
1001003	10.35	5	10.21	2
1001003	9.76	6	10.21	2

 


FreelanceReinh
Jade | Level 19

@jksthomas wrote:

Prog works fine from 3rd row, however, for the second row SEQ_MINIM is blank. Is there a way to display seq = 1 .



This does not happen if the input dataset (HAVE) does not already contain the derived variables (MINIM, SEQ_MINIM). So, make sure that you don't run the step, e.g., on the result of a previous run (like data have; set have; ...). If dataset HAVE for some reason contains variables MINIM or SEQ_MINIM, just drop them via a dataset option:

set have(drop=minim seq_minim);

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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