10

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.)

skaffman
  • 398,947
  • 96
  • 818
  • 769
Simon Nickerson
  • 42,159
  • 20
  • 102
  • 127

5 Answers5

10

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
  • 321
  • 2
  • 2
7

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
  • 2,307
  • 1
  • 17
  • 16
  • +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 Sep 09 '09 at 14:00
5

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
  • 4,465
  • 17
  • 21
  • +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 Sep 09 '09 at 13:59
3

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
  • 42,159
  • 20
  • 102
  • 127
  • @Chang Chung I know it is an old question, but I was redirected here. Is there any reason why you prefer this over cmjohns' solution? @Simon Same question to you: why do you call it a bit fiddly? Is it not 100% stable? – Yoh May 04 '11 at 18:57
  • @Yohsoog: it works, and it's stable. I was just hoping there was a way to do it without looking in sashelp.vcolumn. – Simon Nickerson May 05 '11 at 08:28
0

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. 
Triad sou.
  • 2,969
  • 3
  • 23
  • 27
  • 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 Jan 14 '10 at 22:17