tags:

views:

269

answers:

5

If I have a numeric variable with a format, is there a way to get the formatted value as a character variable?

e.g. I would like to write something like the following to print 10/06/2009 to the screen but there is no putformatted() function.

data test;
  format i ddmmyy10.;
  i = "10JUN2009"d;
run;

data _null_;
  set test;
  i_formatted = putformatted(i); /* How should I write this? */
  put i_formatted;
run;

(Obviously I can write put(i, ddmmyy10.), but my code needs to work for whatever format i happens to have.)

+2  A: 

I can do this with macro code and sashelp.vcolumn but it's a bit fiddly.

proc sql noprint;
  select trim(left(format)) into :format
    from sashelp.vcolumn
    where libname eq 'WORK' and memname eq 'TEST';
run;

data test2;
  set test;
  i_formatted = put(i, &format);
  put i_formatted;
run;
Simon Nickerson
I like this over cmjohns'
Chang Chung
+3  A: 

This seemed to work for a couple that I tried. I used VARFMT and a macro function to retrieve the format of the given variable.

 data test;
  format i ddmmyy10. b comma12.;
  i = "10JUN2009"d;
  b = 123405321;
run;


%macro  varlabel(variable) ;
  %let dsid=%sysfunc(open(&SYSLAST.)) ;
  %let varnum=%sysfunc(varnum(&dsid,&variable)) ;
  %let fmt=%sysfunc(varfmt(&dsid,&varnum));
  %let dsid=%sysfunc(close(&dsid)) ;
  &fmt
%mend varlabel;

data test2;
  set test;
  i_formatted = put(i, %varlabel(i) );
  b_formatted = put(b, %varlabel(b) );
  put i_formatted=;
  put b_formatted=;
run;

This gave me:

i_formatted=10/06/2009
b_formatted=123,405,321
cmjohns
+1, and I am accepting this answer because it is considerably faster than putn(i, vformat(i)). For 10 million observations, this method took 10 seconds, compared to 65 seconds.
Simon Nickerson
+4  A: 

Use vformat() function.

/* test data */
data test;
  i = "10jun2009"d;
  format i ddmmyy10.;
run;

/* print out the value using the associated format */
data _null_;
  set test;
  i_formatted = putn(i, vformat(i));
  put i_formatted=;
run;
/* on log
i_formatted=10/06/2099
*/
Chang Chung
+1 I like this, and didn't know about either putn() or vformat() before now, but I am accepting cmjohns's answer for performance reasons.
Simon Nickerson
A: 

Yes, there is a putformatted() function. In fact, there are two: putc() and putn(). Putc handles character formats, putn() numeric. Your code will need to look at the format name (all and only character formats start with "$") do determine which to use. Here is the syntax of putc (from the interactive help):

PUTC(source, format.<,w>)

Arguments

source is the SAS expression to which you want to apply the format.

format. is an expression that contains the character format you want to apply to source.

w specifies a width to apply to the format.

Interaction: If you specify a width here, it overrides any width specification in the format.

Jonathan Goldberg
But I have to supply the format: the point of the question was to find out if there was a way of formatting with the current format for the variable
Simon Nickerson
+1  A: 

The VVALUE function formats the variable passed to it using the format associated with the variable. Here's the code using VVALUE:

data test;
  format i ddmmyy10.;
  i = "10JUN2009"d;
run;

data _null_;
  set test;
  i_formatted = vvalue(i);
  put i_formatted;
run;

While cmjohns solution is slightly faster than this code, this code is simpler because there are no macros involved.

secoskyj
+1: just what I was after. Thank you!
Simon Nickerson