%macro FirstCap (S); %* Richard A. DeVenezia; %* Given an ALL caps string, convert it to one %* where only the first letter of each word is capitalized.; %* For use in data step only; %* Usage: %* %FirstCap (<name of data step variable>); %*; %* ensure no collision with existing dataset variables; %local random L I c pc; %let random = %sysfunc (ranuni(0), 10.8); %let random = _%substr(&random,3); %let L = L&random.L; %let I = I&random.I; %let c = c&random.c; %let pc = pc&random.pc; length &c $1; &L = length (&S); &c = substr(&S,1,1); do &I = 2 to &L; &pc = &c; &c = substr (&S,&I,1); * only lowercase if current char is uppercase and the previous * char was a letter (if no internal lowercase characters then the * 'or' can be removed); * add more 'or's to deal with punctuation or numbers; if ('A' <= &c <= 'Z' and ('A' <= &pc <= 'Z' or 'a' <= &pc <= 'z')) then substr (&S,&I,1) = lowcase(&c); end; drop &L &I &c &pc; %mend FirsCap;
Sample code
/* data names (keep=name); length name $60; do i = 1 to 1e5; p = 1; name = ''; nW = 2 + 3 * ranuni (0); do w = 1 to nW; nL = 3 + 10 * ranuni (1); do j = 1 to nL; substr (name, p, 1) = byte (65 + 26 * ranuni (2)); p ++ 1; end; p ++ 1; end; output; end; run; options mprint; data names2; set names; newName = name; %FirstCap (newName); run; */