I have 2 sas output tables. First table has a,b,c columns and second table has d,e,f columns
First table is :
a b c
1 2 3
4 5 6
Second table is :
d e f
7 8 9
Is it possible to append them in one sheet with desired output
a b c
1 2 3
4 5 6
d e f
7 8 9
Yes, you can append the second table to the first using proc append , you just need to rename the columns in second table before appending.
proc append base=table1 data=table2(rename=(d=a e=b f=c)) ;run;
Full Code:
data table1;
input a b c;
datalines;
1 2 3
4 5 6
;
run;
data table2;
input d e f;
datalines;
7 8 9
;
run;
proc append base=table1 data=table2(rename=(d=a e=b f=c)) ;run;
Table1 will look like this after appending:
a=1 b=2 c=3
a=4 b=5 c=6
a=7 b=8 c=9
Another Option: If all your data is characters, you just need a create a third table to hold the column names you want to append.
Full Code:
data table1;
input a $ b $ c $;
datalines;
1 2 3
4 5 6
;
run;
data table2;
input d $ e $ f $;
datalines;
7 8 9
;
run;
data table2_names;
input d $ e $ f $;
datalines;
d e f
;
run;
proc append base=table1 data=table2_names(rename=(d=a e=b f=c)) ;run;
proc append base=table1 data=table2(rename=(d=a e=b f=c)) ;run;
Output:
a=1 b=2 c=3
a=4 b=5 c=6
a=d b=e c=f
a=7 b=8 c=9
Related
I'd like to assign to an empty field a value based on many values of other entries. Here my dataset:
input ID date $10. type typea $10. ;
datalines;
1 10/11/2006 1 a
2 10/12/2006 2 a
2 . 2 b
3 20/01/2007 5 p
4 . 1 r
5 11/09/2008 1 ca
5 . 1 cb
5 . 2 b
;
run;
My goal is the following: for all empty entries of the variable "date", assign to it the same date of the record which has the same ID, the same type, but a different typea. If there aren't other records with the criteria described, leave the date field empty. So the output should be:
data temp;
input ID date $10. type typea $10.;
datalines;
1 10/11/2006 1 a
2 10/12/2006 2 a
2 10/12/2006 2 b
3 20/01/2007 5 p
4 . 1 r
5 11/09/2008 1 ca
5 11/09/2008 1 cb
5 . 2 b
;
run;
I tried with something like that based on another answer on SO (SAS: get the first value where a condition is verified by group), but it doesn't work:
by ID type typea ;
run;
data temp;
set temp;
by ID type typea ;
if cat(first.ID, first.type, first.typea) then date_store=date;
if cat(ID eq ID and type ne type and typea eq typea) then do;
date_change_type1to2=date_store;
end;
run;
Do you have any hints? Thanks a lot!
You could use UPDATE statement to help you carry-forward the DATE values for a group.
data have;
input ID type typea :$10. date :yymmdd. ;
format date yymmdd10.;
datalines;
1 1 a 2006-11-10
2 2 a 2006-12-10
2 2 b .
3 5 p 2007-01-20
4 1 r .
5 1 ca 2008-09-11
5 1 cb .
5 2 b .
;
data want;
update have(obs=0) have;
by id type ;
output;
run;
If there are also missing values of TYPEA then those will also be carried forward. If you don't want that to happen you could re-read just those variables after the update.
data want;
update have(obs=0) have;
by id type ;
set have(keep=typea);
output;
run;
I have a dataset in SAS and I want to Convert one column into string by the Product. I have attached the image of input and output required.
I need the Colomn STRING in the outut. can anyone please help me ?
I have coded a data step to create the input data:
data have;
input products $
dates
value
;
datalines;
a 1 0
a 2 0
a 3 1
a 4 0
a 5 1
a 6 1
b 1 0
b 2 1
b 3 1
b 4 1
b 5 0
b 6 0
c 1 1
c 2 0
c 3 1
c 4 1
c 5 0
c 6 1
;
Does the following suggested solution give you what you want?:
data want;
length string $ 20;
do until(last.products);
set have;
by products;
string = catx(',',string,value);
end;
do until(last.products);
set have;
by products;
output;
end;
run;
Here's my quick solution.
data temp;
length cat $20.;
do until (last.prod);
set have;
by prod notsorted;
cat=catx(',',cat,value);
end;
drop value date;
run;
proc sql;
create table want as
select have.*, cat as string
from have inner join temp
on have.prod=temp.prod;
quit;
I don't know how to describe this question but here is an example. I have an initial dataset looks like this:
input first second $3.;
cards;
1 A
1 B
1 C
1 D
2 E
2 F
3 S
3 A
4 C
5 Y
6 II
6 UU
6 OO
6 N
7 G
7 H
...
;
I want an output dataset like this:
input first second $;
cards;
1 "A,B,C,D"
2 "E,F"
3 "S,A"
4 "C"
5 "Y"
6 "II,UU,OO,N"
7 "G,H"
...
;
Both tables will have two columns. Unique value of range of the column "first" could be 1 to any number.
Can someone help me ?
something like below
proc sort data=have;
by first second;
run;
data want(rename=(b=second));
length new_second $50.;
do until(last.first);
set have;
by first second ;
new_second =catx(',', new_second, second);
b=quote(strip(new_second));
end;
drop second new_second;
run;
output is
first second
1 "A,B,C,D"
2 "E,F"
3 "A,S"
4 "C"
5 "Y"
6 "II,N,OO,UU"
7 "G,H"
You can use by-group processing and the retain function to achieve this.
Create a sample dataset:
data have;
input id value $3.;
cards;
1 A
1 B
1 C
1 D
2 E
2 F
3 S
3 A
4 C
5 Y
6 II
6 UU
6 OO
6 N
7 G
7 H
;
run;
First ensure that your dataset is sorted by your id variable:
proc sort data=have;
by id;
run;
Then use the first. and last. notation to identify when the id variable is changing or about to change. The retain statement tells the datastep to keep the value within concatenated_value over observations rather than resetting it to a blank value. Use the quote() function to apply the " chars around the result before outputting the record. Use the cats() function to perform the actual concatenation and separate the records with a ,.
data want;
length contatenated_value $500.;
set have;
by id;
retain contatenated_value ;
if first.id then do;
contatenated_value = '';
end;
contatenated_value = catx(',', contatenated_value, value);
if last.id then do;
contatenated_value = quote(cats(contatenated_value));
output;
end;
drop value;
run;
Output:
contatenated_
value id
"A,B,C,D" 1
"E,F" 2
"S,A" 3
"C" 4
"Y" 5
"II,UU,OO,N" 6
"G,H" 7
so I've been trying to figure out how to rename the ID variable in SAS (I made a dummy dataset to attempt this, see below)
DATA trial;
input hno $ y;
datalines;
a 1
a 2
a 3
a 4
b 3
b 5
cd 5
cd 6
cd 1
;
run;
and what I need to do is have all a=1, b=2, cd=3 and so on, but the code would need to be transferrable to a dataset with ~30,000 observations all with varying ID's. I've been playing around with first.id and last.id but to absolutely no avail. Can anyone help?
Thank you in advance!
EDIT
So to clarify, I need code that produce the output:
a 1 1
a 2 1
a 3 1
a 4 1
b 3 2
b 5 2
cd 5 3
cd 6 3
cd 1 3
where the third column there is the ID variable that increases by one for each unique hno value
If you data are sorted by HNO this will encode HNO to an index. RENAME in SAS usually refers to objects like variables, data sets, etc.
DATA trial;
input hno $ y;
datalines;
a 1
a 2
a 3
a 4
b 3
b 5
cd 5
cd 6
cd 1
;
run;
data trial2;
set trial;
by hno;
if first.hno then id + 1;
run;
proc print;
run;
If your input aren't sorted you created and index ID data set using PROC SUMMARY and the add the ID with a KEYed SET.
DATA trial;
input hno $ y ##;
datalines;
a 1 a 2 b 3 b 5 cd 5 cd 6 a 3 a 4
cd 1
;
run;
proc summary nway data=trial;
class hno;
output out=index(drop=_type_ _freq_ rename=(_level_=id) index=(hno)) / levels;
run;
proc print;
run;
data trial2;
set trial;
set index key=hno/unique;
run;
proc print;
run;
You can also try the format
proc format;
value $ cn
'a' = 1
'b' = 2
'cd' = 3
;
run;
DATA trial;
input hno $ y;
*format hno $cn.;
id = put(hno, $cn.);
datalines;
a 1
a 2
a 3
a 4
b 3
b 5
cd 5
cd 6
cd 1
;
run;
I am working with a very large dataset containing the same columns several times, but with different column names (both character and numeric).
Does anyone know how to find and delete these identical columns?
Example
A B C D E F G
12 ab 12 ab 8 h 12
14 cd 14 cd 65 j 14
6 fs 6 fs 3 g 6
. . . . 4 q .
3 d 3 d 5 d 3
A-G are variable names, and I want to be able to see that A, C and G are identical and then remove all except one.
Also B and D are identical. I want to keep only one.
Is this even possible?
Here is example using technique proposed by Shenglin Chen in the comments.
data have ;
input A B $ C D $ E F $ G ;
cards;
12 ab 12 ab 8 h 12
14 cd 14 cd 65 j 14
6 fs 6 fs 3 g 6
. . . . 4 q .
3 d 3 d 5 d 3
;;;;
Find the unique numeric columns.
proc transpose data=have out=tall_numbers ;
var _numeric_;
run;
proc sort data=tall_numbers nodupkey out=keep_numbers(keep=_name_);
by col: ;
run;
Find the unique character columns.
proc transpose data=have out=tall_characters ;
var _character_;
run;
proc sort data=tall_characters nodupkey out=keep_characters(keep=_name_);
by col: ;
run;
Get the combined list of columns.
proc sql noprint ;
select _name_
into :keep_list separated by ' '
from (select _name_ from keep_characters
union select _name_ from keep_numbers)
order by 1
;
quit;
Make new table with only the unique columns.
data want ;
set have ;
keep &keep_list ;
run;