turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- Used function cat for numeric number with format z...

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

2 weeks ago

`Hello,`

I can not understand why cat does not take into account the zeros in this example.

The length of the macro variable x3 is 2 for months <10 after put (x2,Z2.).
Another question, why the repeat function when the number of repetitions equal to 0

adds the 0 (which explains the use of the loop)

```
%macro remplir();
%DO LOOP=7 %to 12;
%LET x1=%SYSFUNC(INTNX(month,%SYSFUNC(INTNX(day,%SYSFUNC(today()),%SYSFUNC(day(%SYSFUNC(today())))-1)),&LOOP.-19));
%LET x2=%SYSFUNC(MONTH(&x1.));
%LET x3=%SYSFUNC(PUTN(&x2., Z2.));
%let len=%length(&x3.);
%let len1=%length(&x2.);
%LET val1=&x1.;
%LET val12=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,&x3.));
%LET val13=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,%sysfunc(repeat(0,%eval(2-%length(&x2.)))) ,&x2.));
%if &len1.=1 %then %do;
%LET val14=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,%sysfunc(repeat(0,%eval(2-%length(&x2.)))) ,&x2.));
%end;
%else %do;
%LET val14=%SYSFUNC(CAT(%SYSFUNC(PUTN(&x1.,year2.)),M,&x3.));
%end;
%put &=x3/&=len./&=val12./&=val12./&=val13./&=val14.;
%end;
%mend remplir;
%remplir;
```

/**************/

Log

/*************/

Log

X3=11/LEN=2/VAL12=16M11/VAL12=16M11/VAL13=16M011/VAL14=16M11

X3=12/LEN=2/VAL12=16M12/VAL12=16M12/VAL13=16M012/VAL14=16M12

X3=01/LEN=2/VAL12=17M1/VAL12=17M1/VAL13=17M01/VAL14=17M01

X3=02/LEN=2/VAL12=17M2/VAL12=17M2/VAL13=17M02/VAL14=17M02

X3=03/LEN=2/VAL12=17M3/VAL12=17M3/VAL13=17M03/VAL14=17M03

X3=04/LEN=2/VAL12=17M4/VAL12=17M4/VAL13=17M04/VAL14=17M04

`cordially`

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to mansour_ibrahim

2 weeks ago

Why, in $DEITY's name, are you doing that in a macro? The macro facility is a CODE GENERATOR, not a DATA PROCESSOR!!!. Use a data step!

That %sysfunc avalanche is a cancer-causing eyesore.

In the data step, use put's whenever you assign/create a variable, to see how your data is modified. The data step also notifies you of all automatical type conversions where formats might be lost.

---------------------------------------------------------------------------------------------

Maxims of Maximally Efficient SAS Programmers

Maxims of Maximally Efficient SAS Programmers

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to mansour_ibrahim

2 weeks ago

Sorry, that code is nigh on impossible to read. Why not use a simple datastep to achieve your goal?

data _null_; do i=7 to 12; /* do some things here */ end; call symput('len',lengthn(...)); ... run;

Though I can't actually see why you would need all those macro variables in the first place. It would be far simpler if you put the calculation output in datasets and used merges - or are you planning on using this information in filenames/dataset names? If so consider doing all the programming using one dataset and split it out at the end - will simplfy coding quite a bit.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

2 weeks ago

Thank you for your answers

I simplify the example.

Why cat does not take into account the 0?

```
%let x1=2010;
%LET x2=01;
%LET x3=%SYSFUNC(CAT(&x1.,M,&x2.));
%put &x3.;
```

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to mansour_ibrahim

2 weeks ago - last edited 2 weeks ago

Oh, and to fix it just do:

%let x1=2010; %let x2=01; %let x3=&x1.M&x2.; %put &x3.;

You don't need cat() at all.

You will find this post helpful:

https://communities.sas.com/t5/General-SAS-Programming/Why-is-CAT-removing-leading-zeros/td-p/329883

As always, the problem lies with doing data processing in macro language. Macro is for generating text, nothing more, and has limited functionality. In your case the cat() function is treating 01 as numeric, which is 1. You can use put in there as well, however best method is to use the tool appropriate to the task, and data processing is best done in Base SAS - in fact macro is just an addon.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to mansour_ibrahim

2 weeks ago

cat DOES take leading zeroes into account:

```
data _null_;
x1 = '2017';
x2 = '09';
x3 = cat(x1,'M',x2);
put x3=;
run;
```

Result:

2017M09

But try this:

```
data _null_;
x1 = 2017;
x2 = 09;
x3 = cat(x1,'M',x2);
put x3=;
run;
```

Result:

x3=2017M9

So you can see that your "problem" comes from your abuse of the macro facility.

---------------------------------------------------------------------------------------------

Maxims of Maximally Efficient SAS Programmers

Maxims of Maximally Efficient SAS Programmers

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to mansour_ibrahim

2 weeks ago

Looks like an awful lot of work to simulate the use of the YYMMw. format with.

Generally you are better off leaving dates as date values until a human has to read them.

For instance

data _null_; x= '15Dec2016'd; put x yymm5.; run;

which is the value of your macro variables Val12 and Val14 on the second line of log output. (picked on December of personal reasons)