BookmarkSubscribeRSS Feed
makset
Obsidian | Level 7

hello

 

I am looking for the simplest solution to the problem presented below

data A;
input id y; 
cards;
1 50
2 30
3 30
4 60
5 70
6 80
7 70
2 30
run;

data B;
input id changeY; 
cards;
3 300
4 472
5 111
6 2010
run;

result:   if A.id = B.id then y + changeY;

in table A

1 50
2 30
3 330
4 532
5 181
6 2810
7 70
2 30

 

Thank you for your help
7 REPLIES 7
PGStats
Opal | Level 21
proc sql;
update a
set y = sum(y, (select changeY from b where a.id=b.id));
quit;
PG
makset
Obsidian | Level 7

Ok thank you, unfortunately it did not work in this case:

set y = y * (select changeY from b where a.id=b.id);

 

PGStats
Opal | Level 21

Try

 

set y = y * coalesce((select changeY from b where a.id=b.id), 1);

PG
Kurt_Bremser
Super User

A simple merge can do it:

data A;
input id y; 
cards;
1 50
2 30
3 30
4 60
5 70
6 80
7 70
2 30
;

data B;
input id changeY; 
cards;
3 300
4 472
5 111
6 2010
;

data want;
merge a b;
by id;
y = sum(y,changey);
drop changey;
run;

untested, posted from my tablet.

ketpt42
Quartz | Level 8

If your actual datasets are quite large, the best way (IMO) is to do this is with a hash object.

 

data result;
    if _n_=1 then do;
        declare hash b(dataset:"b");
        b.DefineKey("id");
        b.DefineData("changeY");
        b.DefineDone();
        if 0 then set b;
    end;
    
    set a;
    
    if b.find() = 0 then y = sum(y, changey);
    
    drop changeY;
run;
Tom
Super User Tom
Super User

Even better would be to use MODIFY statement to update the existing A dataset instead of creating a new dataset.   If A is large that will reduce a lot of I/O and disk usage.  Risk is that you will no longer have the un-modified version of A.

 

Your case is like example 3 in this version of the documentation.  https://documentation.sas.com/?docsetId=lestmtsref&docsetTarget=n0g9jfr4x5hgsfn17gtma5547lt1.htm&doc...

 

data A;
  if _n_=1 then do;
    declare hash b(dataset:"b");
    b.DefineKey("id");
    b.DefineData("changeY");
    b.DefineDone();
    if 0 then set b(keep=changeY);
  end;
  
  modify A;
  
  if 0=b.find() then do;
    y = sum(y, changey);
    replace;
  end;

run;

Results:

NOTE: There were 4 observations read from the data set WORK.B.
NOTE: There were 8 observations read from the data set WORK.A.
NOTE: The data set WORK.A has been updated.  There were 4 observations rewritten, 0 observations added and 0 observations deleted.


Obs    id       y

 1      1      50
 2      2      30
 3      3     330
 4      4     532
 5      5     181
 6      6    2090
 7      7      70
 8      2      30

 

makset
Obsidian | Level 7

Thank you for solving my problem and broadening the horizon :). I have one more problem (similar in my opinion) could you help me too?

data A;
informat datetime  datetime21.;
input datetime A B; 
format datetime  datetime21.;
cards;
   02JUN2003:21:58:00	1	8
   02JUN2003:21:58:30	2	2
   02JUN2003:21:59:00	5	3
   02JUN2003:21:59:30	8	7
   02JUN2003:22:00:00	3	2
   02JUN2003:22:00:30	4	0
   02JUN2003:22:01:00	8	0.8
   02JUN2003:22:01:30	3	1
   02JUN2003:22:02:00	2	7
   02JUN2003:22:02:30	5	3
   02JUN2003:22:03:00	2	5
   02JUN2003:22:03:30	7	8
   02JUN2003:22:04:00	9	7
   02JUN2003:22:04:30	10	2
   02JUN2003:23:05:00	6	6
   02JUN2003:23:05:30	3	7
   02JUN2003:23:06:00	7	6
run;



data B;
informat datetimeL  datetime21. datetimeR  datetime21.;
input datetimeL datetimeR move; 
format datetimeL datetimeR  datetime21.;
cards;
02JUN2003:22:00:00	02JUN2003:22:59:59	1
02JUL2003:17:00:00	02JUL2003:17:59:59	1
01AUG2003:23:00:00	01AUG2003:23:59:59	3
run;

pseudocode: if A.datetime between B.datetimeL and B.datetimeP then A.datetime = INTNX('second',A.datetime,B.move * 60)

data Result;
informat datetime  datetime21.;
input datetime; 
format datetime  datetime21.;
cards;
   02JUN2003:21:58:00	1	8
   02JUN2003:21:58:30	2	2
   02JUN2003:21:59:00	5	3
   02JUN2003:21:59:30	8	7
   02JUN2003:23:00:00	3	2
   02JUN2003:23:00:30	4	0
   02JUN2003:23:01:00	8	0.8
   02JUN2003:23:01:30	3	1
   02JUN2003:23:02:00	2	7
   02JUN2003:23:02:30	5	3
   02JUN2003:23:03:00	2	5
   02JUN2003:23:03:30	7	8
   02JUN2003:23:04:00	9	7
   02JUN2003:23:04:30	10	2
   02JUN2003:23:05:00	6	6
   02JUN2003:23:05:30	3	7
   02JUN2003:23:06:00	7	6
run;

Thank you for your help

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
  • 7 replies
  • 1377 views
  • 4 likes
  • 5 in conversation