- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have a variable that is made up of 15 letters, sometimes less. I have to put that text into string format with a fixed length of 17, left justify it and then pad the leading portion with blank spaces, for those which are 15 letters or less.
For example:
Var1= AAAAAAA I want to let Var 2 = "AAAAAAA "
I need this because I will concatenate variables and I need the blanks, for Example:
Var 2 = "AAAAAAA ", Var 3= x, Var 4 = z
I need -----> VarFinally= "AAAAAAA xz"
Any suggestion welcome.
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Try this to see if it provides the desired results.
Thanks,
data have;
infile datalines;
input var1 $ 1-9 @10 var2 $1. @12 var3 $1.;
datalines;
AAAA z x
AAAAAAAA t y
AAAA r q
AAAAAAA s e
;
data want;
length var1 $15. varfinal $17.;
set have;
varfinal=left(cat(var1,var2,var3));
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi, I have already the data set charged and I want to know how I should use the "@" . Maybe making a FORMAT ?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
If you have data then use only
data want;
length var1 $15. varfinal $17.;
set have;
varfinal=left(cat(var1,var2,var3));
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You asked
MAAT wrote:
Hi, I have already the data set charged and I want to know how I should use the "@" . Maybe making a FORMAT ?
I think the answer might be to use the SUBSTR() function
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps I do not understand the question, but if you have a variable that is 15 characters long and you want to use it to make a new one that is 17 characters long by appending two characters to it why not just do that?
data want ;
length var1 $15 var2 $17 var3 $1 var4 $1 ;
set have ;
var2 = var1 || var3 || var4 ;
run;
Now if for some reason the values in VAR1 have leading blanks that you want to move to the end then use the LEFT() function.
var2 = left(var1) || var3 || var4 ;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi Tom,
That was my first option, but the || doesn´t work with " " (blanks) if you make x=Var1||" " then x = var1, and it doesn´t solve any! :S
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
SAS character variables are fixed length. So you just need to define the variables to have the length that you want.
How did you define the lengths of your variables? If you just let SAS guess it might not make variables with the lengths that you want. From the words in your original post it looks like you want to define VAR2 with length of $15 and VarFinally with a length of $17. Looking also at you pseudo code it looks like you should define Var3 and Var4 as length $1. Length of Var1 does not matter as long as it is less than or equal to VAR2, otherwise assigning a value from var1 into var2 will be truncated.
Check the results of this little test.
data sloppy;
Var1= 'AAAAAAA';
Var2= 'AAAAAAA ';
Var3= 'x' ;
Var4 = 'z' ;
VarFinally= Var2||Var3||Var4 ;
run;
data neat ;
length var1 $8 var2 $15 Var3 Var4 $1 VarFinally $17 ;
Var1= 'AAAAAAA';
Var2= 'AAAAAAA ';
Var3= 'x' ;
Var4 = 'z' ;
VarFinally= Var2||Var3||Var4 ;
run;
proc compare data=sloppy compare=neat;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Actually if the length of X was not previously defined then X=VAR1||' '; would indeed make a variable X with the value of VAR1 padded on the right with one more blank that was already on the end of VAR1. The length of the new variable X would be defined as the length of the existing variable VAR1 plus one.
SAS variables are fixed length and are always padded with blanks to the full length. (There is no such thing as a VARCHAR() type like you might have in a database system.)
So if VAR1 is of length $10 the following two statements will assign the exact same value to VAR1.
data x;
length VAR1 $10;
var1='ABC';
var1='ABC ';
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
In SAS character variables are fixed length (padded with blanks). If your variables have already the right length then you only need to left align them before concatenation. Execute below sample code and have a look into the resulting SAS table.
data sample;
length var1 var2 $17 var_concat $34;
length syntax_used $50.;
var1='AAA';
var2='BBB';
var_concat=var1||var2;
syntax_used='var_concat=var1||var2;';
output;
var1=' AAA';
var2=' BBB';
var_concat=var1||var2;
syntax_used='var_concat=var1||var2;';
output;
var_concat=left(var1||var2);
syntax_used='var_concat=left(var1||var2);';
output;
var_concat=left(var1)||left(var2);
syntax_used='var_concat=left(var1)||left(var2);';
output;
var_concat=cat(left(var1),left(var2));
syntax_used='var_concat=cat(left(var1),left(var2));';
output;
var_concat=put(left(var1),$6.)||put(left(var2),$6.);
syntax_used='put(left(var1),$6.)||put(left(var2),$6.);';
output;
var_concat=substrn(left(var1),1,6)||substrn(left(var1),1,6);
syntax_used='substrn(left(var1),1,6)||substrn(left(var1),1,6);';
output;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Hi Patrick, I thing the variables are fixed length but if I need concatenate after with another variable, SAS "forget" to put the blank fields, and it is the problem! I need the blanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
SAS does not "forget" the trailing blanks. However, when making a comparison between two character variables as a convenience it in effect trims (removes trailing blanks) for the purpose of making the comparison and only during the comparison.
The alternative would be that you would have to extend the shorter variable with blanks in order to compare two variables of unequal length. Maybe this is what SAS is doing "under the covers" anyway. The effect is the same.
This is a convention that has been adopted by SAS and I think they made the right choice. It would be tedious to have to check the length of each variable before making a comparison, in case the comparison would fail each time the lengths were different.
An alternate design would have used byte(0) ( '00'x ) for padding in which case the number of trailing blanks would not change if the value is copied into a variable with longer length, and would be significant in comparisons. It's one of the early design decisions that become fundamental to the language.
You can see that SAS retains trailing blanks
data test ;
length var $ 12 ;
var = 'ABC' ;
var = var || 'XYZ' ;
put var= ;
run ;
Because var is defined with length 12 the value ABC is padded with 9 blanks. It then has no space left to add on the XYZ.
Macro variables, on the other hand, do not have fixed length and they can be extended, so you get a different result:
%Let var = %Str(ABC ) ;
%Let var = &var.XYZ ;
%Put &var ;
Richard
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
If you want to create VarFinally based on the values in VAR1,VAR3 and VAR4 and you have no control over how the lengths of those variables were defined (say you imported them from Excel) then a little defensive coding will make it possible.
data WANT ;
set HAVE;
length VarFinally $17. ;
VarFinally = substr(var1||repeat(' ',15)),1,15)||substr(var3,1)||substr(var4,1);
run;