data name ;
input (v1-v5) ($) ;
cards ;
john peter max jann kiyaa
;
how to concatenate all variables of first letter like below
jpmjk
data name ;
input (v1-v5) ($) ;
array _v(5) $ v1-v5;
length want $8.;
do i= 1 to 5;
want=catt(want,substr(_v(i),1,1));
end;
drop i;
cards ;
john peter max jann kiyaa
;
run;
This works too.
data name ;
input (V1-V5) ($) ;
array _V(5) $1 V1-V5;
WANT=_V[1]||_V[2]||_V[3]||_V[4]||_V[5];
cards ;
john peter max jann kiyaa
run;
@mkeintz Calling on your PDV expertise. Do you understand why
WANT=cats(_V[1],_V[2],_V[3],_V[4],_V[5]);
or
WANT=cats(of _V[*]);
don't work?
Hi @ChrisNZ;
I tried your solution but i didn't get the result.
Your Code Result: jomjk
It looks like _V[2] is John's second letter 'o'.
Wow this is crazy. Add
putlog _V[1]= _V[2]= _V[3]= _V[4]= _V[5]=;
and you get
V1=j V2=p V3=m V4=j V5=k
Even worse, add
WANT=_V[1]||_V[2]||_V[2]||_V[3]||_V[4]||_V[5];
and you get
WANT=jopmjk
Do you have the same behaviour?
Yes exactly the same result 🙂
But I didnt get it.
I looked some documents but couldn't find anything.
This looks like a defect. Or at least something I don't understand. I'll contact tech support.
Update: R&D are still investigating, but I dug a bit depper.
I was puzzled as to why function cats() should get a different value (the full string)? What’s special about it?
That quirkiness got me thinking. If some functions get a special treatment and can ignore variable length (and why should they?),
which other functions do this? Is there at least consistency about functions?
The answer is no. I tested a few functions and the behaviour varies (as seen in the suffix of the names).
A_ALL=put (_V[2],$upcase20. );
B_ONE=putc (_V[2],'$upcase20.');
C_ALL=count (_V[2],'e' );
D_ALL=countc (_V[2],'e' );
E_ONE=left (_V[2] );
F_ALL=length (_V[2] );
G_ALL=lengthn (_V[2] );
H_ALL=find (_V[2],'e' );
I_ALL=index (_V[2],'e' );
J_ONE=lowcase (_V[2] );
K_ONE=propcase (_V[2] );
L_ONE=upcase (_V[2] );
M_ALL=reverse (_V[2] );
N_ALL=right (_V[2] );
O_ONE=trim (_V[2] );
P_ONE=scan (_V[2],1 );
Q_ONE=strip (_V[2] );
R_ALL=tranwrd (_V[2],'e','E' );
S_ONE=translate(_V[2],'x','p' );
T_ALL=quote (_V[2] );
U_ONE=compress (_V[2] );
V_ONE=compbl (_V[2] );
W_ALL=prxmatch ('/e/',_V[2] );
X_ALL=prxchange('s/p/x/',1,_V[2] );
Y_ALL_THEN_ONE=substr(_V[2],3 );
So put() and putn() don’t behave the same. Left() and right() don’t either, like tranwrd() and translate().
Substr() does a bit of both (reads the full string but returns a one-character length result).
To be continued...
Final update.
After weeks of tech support talking to R&D, the conclusion is... drum roll... "Don't do this". 🙂
No explanation, simply:
The ARRAY definition attempts to 'trick' or change the length of the variables to a length of 1. This is not a recommended practice. 8><. The recommended method would be to use SUBSTR function.
Or even the FIRST function I might add.
There we go. Case closed. 🙂
data want;
length newvar $5.;
input (v1-v5) ($) ;
call catt(newvar,substr(v1,1,1),substr(v2,1,1),substr(v3,1,1),substr(v4,1,1),substr(v5,1,1));
cards ;
john peter max jann kiyaa
;
run;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.