Reputation: 3082
I have created a formats like following
data formatset;
input fmtname $ start $ end $ label $;
datalines;
$test region1 region3 zone1
$test region4 region5 zone2
$test region6 region7 zone3
;
run;
proc format library = work.formats
cntlin = work.formatset;
run;
quit;
Problem: I will have new datalines data with the variable region
. And i want to have a new attribute zone
which use the format $test.
data output;
input region $;
format zone $test.;
zone = region;
datalines;
region1
region2
region3
region4
region5
region6
region7
region8
;
run;
Upvotes: 0
Views: 142
Reputation: 51621
The problem is that you did not define your variable ZONE before assigning a format to it. So SAS used the default length of the assigned format to define the variable zone. You could fix this by moving the FORMAT statement to after the assignment statement. Then SAS would assume that ZONE should have the same length as REGION.
But the real solution is to define your variables before using them or attaching formats to them.
data output;
length region $8 zone $8 ;
input region;
zone = region;
format zone $test.;
cards ;
...
If you want the value of ZONE to be the value that the $TEST. format would display then use the PUT() function in the assignment statement, instead of attaching the format to the variable.
zone = put(region,$test.);
Upvotes: 1
Reputation: 3845
With format zone $test.;
, you created a variable zone
with internal length $5
(five characters). To proof that, run
proc contents data=output;
run;
With zone = region;
you assign the value of your region
to zone
, which is then truncated to 5 characters. The label is only applied when you print or list the data. At that point in time the variable zone
contains the text "regio", which is not in one of the start
to end
ranges and hence is not translated.
One way to cure it is to apply the format already when you assign a value to zone
, writing zone = put(region, $test);
.
Another one is to explicitly specify the storage length of zone with length zone $7;
before giving it a format, or do both at once with format zone $test.;
like the other answer suggests.
When you create a character format using a cntlin
, in proc format
, it receives as length the maximum label length, in your case 5 characters. This length is the number of characters a variable with that format is stored with.
You can see that if you run
proc format library = work.formats
cntlin = work.formatset;
run;
This is not logical, indeed, and what is worse: you cannot change that by specifying a length in your cntlin
dataset.
Simply specify any value for which the format should display something of 8 bytes long:
data formatset;
input fmtname $ start $ end $ label $;
datalines;
$test region1 region3 zone1
$test region4 region5 zone2
$test region6 region7 zone3
$test _dummy_ _dummy_ 1234567
;
run;
Upvotes: 1
Reputation: 9569
You need to specify a width when using your format to make sure that enough of the characters are read from your zone
variable. Try format zone $test7.;
in your second data step.
If you don't specify a width, SAS defaults to the maximum length of any of the displayed values defined for the format. It will then read only that many characters (in your case 5) from the formatted variable when looking for formatted values to display, and if there isn't a value specified in the format for those 5 characters then they are displayed verbatim.
Upvotes: 2