Mike,
In the past, I've solved problems similar to yours using an Attribute statement prior to the set statement.
Data want.......
attrib firstvar.........
secondvar......
thirdvar.........
sex....length=$15.....
fourthvar......;
set have;
run;
Tom
/2 you do not care but SAS techies are. They changed the order for the mentioned reason. For compatibility they had to implement an order translation table.
When you could influence that ordering by that transaction table a lot of people could do easy coding with sas datasets
1/ with a column based dbms changing columns is easy but add in rows not.
3/ see the physical reordering as change it is not the same as in the old days,
4/ that is the reason to code the order and not being dependent of some other. With an external dbms using sql that lazy approach common to sas is not acceptable.
Not to beat on you personally but I would like to emphasize that one of SAS's big strengths is how quickly you can use it to do analysis. What to find the means of all numeric variables in a table, but not sure how to spell every variables name? No problem.
SQL based DBMS systems that cannot handle combining tables where the variables are the same but the column order is different are not user friendly.
It is the DBMS language implementation team being lazy not the users who do not want to have to write out every variable name.
With SAS I can control the order of the variable in a dataset if I want to and still have the flexibility to override that order if I need to.
Similarly where is the support in those languages/systems for user friendly things like variable lists (VAR1- VAR2, NAME -- WEIGHT, ADDRESS: ) .
Ok Tom, I agree with the strengths of sas language for analytics.
Influencing the order of variables on those sas datasets could be an easy to implement enhancement for SAS. Really getting control on the order.
For some reason SAS is not seeing their own strength, their focus is moving to in database processing and sql interfaces. With those sql interfaces hitting all those incompatible sql implementations. I am no a fan of sql for analytics purposes as you are also not I see.
Just to pop my 2p's worth in, I agree with both arguments here. Its not the DBMS developers who were being lazy, you should know what data you are dealing explicitly inside out, therefore being strict about specifying variable names shouldn't be a problem, Toad for instance has an object inspector where you can drag from a contents directly into code, so saving the typing (and the fact that SAS doesn't have this is a real annoyance). The select * syntax for instance, whilst we are all guilty of using it, is the lazy approach, first you are selecting everything even though you may not necessarily need it, and within say macro's could lead to some interesting outcomes.
I also agree that SQL lacking the lists is rather a nuisance however this is down to the concept behind the languages. SQL works on normalized tables, and hence there's really no need to consider long lists of variables as these would be rows.
For my side, I program backwards from a spec, so the spec would be the main item to build, then from that you would order your select, fix lengths etc. then decide where that data came from etc.
An example:
In study A I have four columns:
Parameter result1-result3 (these being lower, upper, mean)
I write a bit of code
... select * from ... and process then output result3 to mean.
In study B I have the same thing, but they have cunningly moved mean between lower and upper:
I copy my code over and get and incorrect result. The same thing, but explicitly stating variables would work in both instances:
Paramter lower mean upper:
... select parameter,mean from ...
(ok, not the best example).
here's a solution
use this macro
/*
change a variable's length without change the position
the parads should be defined as below
do not change the parads's variable
data parads;
length name $32 length 8;
name = "a2";length = 8;output;
name = "a7";length = 200;output;
run;
*/
%macro rclen(ids, parads);
*get all variable names;
proc sql noprint;
create table _cvars as
select upcase(name) as name, length, varnum ,type
from sashelp.vcolumn
where libname='WORK' and memname=upcase("&ids.")
order by name;
quit;
data ¶ds.;
set ¶ds.;
name = upcase(name);
run;
proc sort data=¶ds.;by name;run;
data _cvars;
merge _cvars ¶ds.;
by name;
run;
proc sort data=_cvars;by varnum;run;
%local i dsid nobs rc name tempStr resStr;
%let dsid = %sysfunc(open(_cvars, i));
%let nobs = %sysfunc(attrn(&dsid,NOBS));
%do i=1 %to &nobs.;
%let rc = %sysfunc(fetchobs(&dsid,&i));
%let name=%sysfunc(getvarc(&dsid, %sysfunc(varnum(&dsid,name))));
%let type=%sysfunc(getvarc(&dsid, %sysfunc(varnum(&dsid,type))));
%let length=%sysfunc(getvarn(&dsid, %sysfunc(varnum(&dsid,length))));
%if &type.=char %then %do;
%let tempStr = $&length.;
%end;
%else %do;
%let tempStr = 8;
%end;
%let resStr = &resStr. &name. %left(%trim(&tempStr.)) ;
%end;
%let rc=%sysfunc(close(&dsid));
%put &resStr.;
OPTIONS VARLENCHK= NOWARN;
data &ids.;
length &resStr.;
set &ids.;
run;
OPTIONS VARLENCHK= WARN;
%mend rclen;
here's the test code
data a;
length a1 8 a2 $100 a3 8;
a1 = 1;
a2 = "ad";
a3 = 1;
a4 = 8;
a5 = 8;
a6 = 8;
a7 = "asdfs";
a8 = 8;
a9 = 8;
run;
data parads;
length name $32 length 8;
name = "a2";length = 8;output;
name = "a7";length = 200;output;
run;
%rclen(a, parads);
hope you like it
Simply we can do by the below, suggest me If am wrong
data test;
set sashelp.class;
length Sex $5.;
run;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.