is there another way to do this:
proc sql noprint;
select distinct("'"||usubjid||"'")
into: pksubj separated by ','
from pk;
quit;
or is this already the best way?
proc sql noprint;
select distinct quote(trim(usubjid),"'")
into :pksubj separated by ' '
from pk
;
quit;
.
proc sql noprint;
select distinct quote(trim(usubjid),"'")
into :pksubj separated by ' '
from pk
;
quit;
.
data pk;
set pk dose;
if usubjid in (&pksubj);
run;
I make PK datasets. there is a lot of code that is copied and pasted but typically the next data step is like this. I mean isn't there any better way to do this? Like couldn't subqueries be used in proc sql or something? it's an entire program where the info from dose records has to be carried forward to pk records.
I guess the comma could be unnecessary. I do not normally use quote function but I guess it is more efficient/prettier than using the pipes and concatenating the quotes.
@tarheel13 wrote:
data pk; set pk dose; if usubjid in (&pksubj); run;
I make PK datasets. there is a lot of code that is copied and pasted but typically the next data step is like this. I mean isn't there any better way to do this? Like couldn't subqueries be used in proc sql or something? it's an entire program where the info from dose records has to be carried forward to pk records.
I guess the comma could be unnecessary. I do not normally use quote function but I guess it is more efficient/prettier than using the pipes and concatenating the quotes.
That data step looks strange. Are you really trying to just append two dataset instead of doing a merge?
If you are doing a merge then use the IN= dataset option.
data pk_dose;
merge pk(in=in1) dose;
by usubjid;
if in1;
run;
If you really did want to just stack the data instead of merging it then here is a way you could still take advantage of the IN= dataset option by interleaving the two sources and remembering if the subject was in the PK dataset.
data pk_dose;
set pk(in=in1) dose;
by usubjid;
if first.usubjid then in_pk = in1;
retain in_pk;
if in_pk;
run;
no they cannot be merged. pk and dose need to be combined vertically, not horizontally. is using the in flag also an option with combining datasets vertically?
@tarheel13 wrote:
no they cannot be merged. pk and dose need to be combined vertically, not horizontally. is using the in flag also an option with combining datasets vertically?
Not when simply stacking them. But it you interleave them you can. See the update to the previous answer.
yea basically want to stack dose and pk but don't want to keep pk subjects that weren't in dose.
@tarheel13 wrote:
yea basically want to stack dose and pk but don't want to keep pk subjects that weren't in dose.
So change the order in the SET statement so the DOSE records for a subject appear before the PK records and test if they subject has a DOSE record. You probably also want to use WHERE= to exclude any records in the DOSE dataset that indicate that the subject did not actually get dosed.
awesome, thanks for responding. I learn so much on here. I'm always looking for the best possible way to do things.
The QUOTE function is a bit tidier:
proc sql;
select quote(name)
into :names separated by ','
from sashelp.class;
quit;
%put &names;
I tried that with some fake data and got a trailing blank so maybe you do have to use trim() as @Tom said
Here is another way:
https://communities.sas.com/t5/SAS-Programming/Quote-and-Unquote-a-list/m-p/205514#M38206
But you would need to use proc sql to make a list anyways, so your way could be more convenient in this case. The macro from this post is better when you provide a random typed list that is not a variable.
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!
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.
Ready to level-up your skills? Choose your own adventure.