BookmarkSubscribeRSS Feed
satish123
Fluorite | Level 6

Dear all,

i've a dataset like given bellow

                

ABCD
N363636
Mean9581.17289791.52621366.1106
SD2965.86262982.0749 398.3543
Geo_Mean9170.2867 2.0864674 1312.3213
CV13.95511 13.455669 0.159741

 

Now i need to give 3 decimal places for the variables 'B' & 'C', and 5 significant digits for the variable 'D'. But these decimal places and significant digits should not be applyed for observations of 'N'. i had tried many things like format, length and etc. but it didn't work well. the output should be like given bellow.


ABCD
N363636
Mean9581.1729791.5261366.1
SD2965.8622982.074398.35
Geo_Mean9170.2862.086 1312.3
CV13.955 13.4550.15974


i'm excited to find is it really possible? if so, can anyone tell me how? or it is possible by transforming the variables?

Thanks in advanc

2 REPLIES 2
ballardw
Super User

It might help to describe how you generated the example start data set. That approach may be limiting what you can accomplish.

The basic tool SAS uses for displaying values is a format. However a single variable or column may have only one format associated with it as a dataset characteristic.

The report procedures Report and Tabulate may allow creating displays with the appearance you are requesting.

CCW
Obsidian | Level 7 CCW
Obsidian | Level 7

Hi,

The provided answer is pretty close to what you want but not identical. Note that in my solution, variable D converts to character type since in my opinion, you cannot show the significant digits in numeric type(the problem comes from the appending zero's).

If you don't want to know about the function I wrote, you can just skip it. There are many ways to implement significant digits. Please note that the function sigFig() is a user defined function rather then a SAS data step function.

* YOUR RAW DATA ;
data dat;
  infile datalines;
  input A: $10. B C D;
  datalines;
N        36 36 36
Mean     9581.1728 9791.5262 1366.1106
SD       2965.8626 2982.0749 398.3543
Geo_Mean 9170.2867 2.0864674 1312.3213
CV       13.95511 13.455669 0.159741 
;run;

* SPLIT DATASET ;
data dat_1 dat_2;
  set dat;
  i+1; /* Display order */
  if A = "N" then output dat_1;
  else output dat_2;
run;

*******************************************************************************
* Function we will use: sigFig ;
* Note: It's easy to convert functions in PROC FCMP to data step ;
libname my "/home/wangc187/SAStraining/FCMP"; /* Set your physical location */

proc fcmp outlib=my.func.format;
  function rndgt(x, sf);
  * Round to the specified digit according to significant figure ;
    I=if x < 1 then 0 else 1;
    rd=int(log10(x)) - sf + I;
    return(round(x, 10**rd));
  endsub;
  
  function extsf(x) $30;
  * Extract significant digits from a number ;  
    attrib sfc length=$30;
    xc=compress(put(x, BEST30.)); /* Char. of x */
   * Eliminate the decimal point and leading 0's;
    sfc=prxchange("s/\.//", -1, xc); /* Eliminate decimal point */
    sfc=prxchange("s/0*([1-9][0-9]*)/$1/", -1, sfc); /* Eliminate leading 0's */
    return(sfc);
  endsub;
    
  function sigFig(x, sf) $30;
  * Show significant figure result as a Char. ;   
    attrib sfc length=$30;  
    * 1. Round number ;
    xr=rndgt(x, sf); /* Rounding result */
    xrc=compress(put(xr, BEST30.)); /* Char. of xr */
    * 2. Adding trailing 0's ;
    n0=sf - length(extsf(xr)); /* Number of adding 0's */
    if n0 > 0 then do; /* The case we need to add 0's */
      zeros=repeat("0", n0 - 1); /* zeros we add*/
      out=if index(xrc, ".") then cats(xrc, zeros)
        else cats(xrc, ".", zeros); /* For integer, adding decimal point */
    end;
    else out=xrc;
    return(out);
  endsub;
  
options cmplib=my.func;
  /* Set the searching route according to PROC FCMP outlib= */
******************************************************************************; 

* APPLY FORMATS ;
data dat_2f(drop=D rename=(_D=D));
  set dat_2;
  format B C 10.3;
  _D=sigFig(D, 5);
run;

* APPEND DATASETS ;
* Change data type for variable D in dat_1 for dataset appending ;
data dat_1d(drop=D rename=(_D=D));
  set dat_1;
  _D=put(D, 2.);
run;

* Append ;
proc sql;
create table result(drop=i) as
select *
  from(
    select *
      from dat_1d
      union
    select *
      from dat_2f)
  order by i;
quit;

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

New Learning Events in April

 

Join us for two new fee-based courses: Administrative Healthcare Data and SAS via Live Web Monday-Thursday, April 24-27 from 1:00 to 4:30 PM ET each day. And Administrative Healthcare Data and SAS: Hands-On Programming Workshop via Live Web on Friday, April 28 from 9:00 AM to 5:00 PM ET.

LEARN MORE

Discussion stats
  • 2 replies
  • 11279 views
  • 0 likes
  • 3 in conversation