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;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.