I'm sure there would be plenty of uses for syntax like :
data B;
set A(keep=myLine);
infile _infile_=myLine;
input ... ;
run;
I don't like using code that is heavily dependent on side-effects for any serious work. Syntax like above would be simpler to code and much easier to read and understand.
PG
Art
thank you for providing the solution to my (this time unintentional) error!
I was offering such a basic approach because I see absolutely no reason to make that kind of conversion (num--> char) into a table/dataset. And the original poster offered no context where such a data handling model might be useful or needed by an application. So I thought since data type was to be stripped back to simple text, I thought it might be even more convenient to deliver a collection of these numerics. - and it opens the discussion up, beyond the dictionary tables
Often I adapt the community.org apprach with a : instead of the +0
(it pre-dates community)
Had it appeared useful, I might have introduced a DLM= or better still, DSD on a suitable file statement.
When it comes to re-loading original lengths, despair! Why not just keep numerics numeric?
Can you imagine a context where this conversion helps anything except a homework?
example (red part must be upcase):
data have;
input id $ sex $ a b c d e ;
cards;
1 2 11 22 33 44 55
;
proc sql noprint;
select catx(' ','put(',name,',8.) as',name) into : list1 separated by ','
from dictionary.columns
where libname='WORK' and memname='HAVE' and type ='num' ;
select name into : list2 separated by ','
from dictionary.columns
where libname='WORK' and memname='HAVE' and type ='char' ;
create table want as
select &list1,&list2 from have;
quit;
proc contents data=want;run;
Hi LinLin,
Your code works out very good. The only problem I have is the final dataset WANT has all the variables $200. Is there any way for the char variable to maintain their original format length ?
Thanks
Hi,
I don't know how to maintain the original length. You can assign a fixed length to all the variables.
data have;
input id $ sex $ a b c d e ;
cards;
1 2 11 22 33 44 55
;
proc sql noprint;
select cat('put(',strip(name),',8.) as ',strip(name), ' length=20') into : list1 separated by ','
from dictionary.columns
where libname='WORK' and memname='HAVE' and type ='num' ;
select name into : list2 separated by ','
from dictionary.columns
where libname='WORK' and memname='HAVE' and type ='char' ;
create table want as
select &list1,&list2 from have;
quit;
proc contents data=want;run;
# Variable Type Len
1 a Char 20
2 b Char 20
3 c Char 20
4 d Char 20
5 e Char 20
6 id Char 8
7 sex Char 8
Hi LinLin,
I find some other tedious way of getting back the original attr. It works.
Thanks for all your help.
The following macro, which I found in Appendix 1 a macro book**, does the conversion that you are looking for. It has the advantage of maintaining variable names and labels and uses any numeric formats (such as dates) in the conversion.
**********************;
***A1.6.4
***%ALLCHAR
**********************;
%macro allchar(dsn);
* Determine the numeric vars in &dsn;
proc contents data=&dsn out=cont noprint;
run;
* Create the macro variables for each numeric var;
data _null_;;
set cont(keep=name type format formatl formatd label);
length fmt $15;
where type=1;
* Count the numeric vars and save the total number;
i+1;
ii=left(put(i,3.));
call symput('n',ii);
* create a format string;
fmt = 'best.';
if format ne ' ' then fmt = trim(format)
||trim(left(put(formatl,3.)))
||'.'||left(put(formatd,3.));
fmt = compress(fmt);
call symput('fmt'||ii,fmt);
* Save the variable name;
call symput('name'||ii,name);
* Save the label for this variable;
if label = ' ' then label = name;
call symput('label'||ii,label);
run;
* Establish a data set with only character variables;
* &n number of numeric variables in &dsn;
* __aa&i temporary var to hold numeric values;
* &&name&i name of the variable to covert from numeric;
*
* The numeric value of &name1 is stored in __aa1
* by renaming the variable in the SET statement. __aa1
* is then converted to character and stored in the
* 'new' variable &name1 in the data set CHARONLY.
* ;
data charonly (drop=
%* Drop the temp. vars used to hold numeric values;
%do i=1 %to &n;
__aa&i
%end;
);
length
%* Establish the vars as character;
%do i=1 %to &n;
&&name&i
%end;
$8;
set &dsn (rename=(
%* Rename the incoming numeric var to a temp name;
%* This allows the reuse of the variables name;
%do i=1 %to &n;
&&name&i=__aa&i
%end;
));
* Convert the numeric values to character;
%do i=1 %to &n;
&&name&i = left(put(__aa&i,&&fmt&i));
label &&name&i = "&&label&i";
%end;
run;
proc contents data=charonly;
proc print data=charonly;
run;
%mend allchar;
%allchar(sasclass.biomass)
** Appendix 1 of Carpenter's Complete Guide to the SAS Macro Language, 2nd Edition. Used with the permission of the author.
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 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.