The below is the sample data. I want to split variables for every 200 characters however it should be end by last delimiter less than 200 meaningfully. I have attached the desired output for easy reference.
Variables should split like Var1, Var2, Var3, so on...
Please help me on how to achieve this requirement and let me know if any further information is required.
data test;
var = "A1; A2; A3; A4; A5; A6; A7; A8; A9; A10; A11; A12; A13; A14; A15; A16; A17; A18; A19; A20; A21; A22; A23; A24; A25; A26; A27; A28; A29; A30; A31; A32; A33; A34; A35; A36; A37; A38; A39; A40; A41; A42; A43; A44; A45; A46; A47; A48; A49; A50; A51; A52; A53; A54; A55; A56; A57; A58; A59; A60; A61; A62; A63; A64; A65; A66; A67; A68; A69; A70; A71; A72; A73; A74; A75; A76; A77; A78; A79; A80; A81; A82; A83; A84; A85; A86; A87; A88; A89; A90; A91; A92; A93; A94; A95; A96; A97; A98; A99; A100; A101; A102; A103; A104; A105; A106; A107; A108; A109; A110; A111; A112; A113; A114; A115; A116; A117; A118; A119; A120; A121; A122; A123; A124; A125; A126; A127; A128; A129; A130; A131; A132; A133; A134; A135; A136; A137; A138; A139; A140; A141; A142; A143; A144; A145; A146; A147; A148; A149; A150; A151; A152; A153; A154; A155; A156; A157; A158; A159; A160; A161; A162; A163; A164; A165; A166; A167; A168; A169; A170; A171; A172; A173; A174; A175; A176; A177; A178; A179; A180; A181; A182; A183; A184; A185; A186; A187; A188; A189; A190; A191; A192; A193; A194; A195; A196; A197; A198; A199; A200; A201; A202; A203; A204; A205; A206; A207; A208; A209; A210; A211; A212; A213; A214; A215; A216; A217; A218; A219; A220; A221; A222; A223; A224; A225; A226; A227; A228; A229; A230; A231; A232; A233; A234; A235; A236; A237; A238; A239; A240; A241; A242; A243; A244; A245; A246; A247; A248; A249; A250; A251; A252; A253; A254; A255; A256; A257; A258; A259; A260; A261; A262; A263; A264; A265; A266; A267; A268; A269; A270; A271; A272; A273; A274; A275; A276; A277; A278; A279; A280; A281; A282; A283; A284; A285; A286; A287; A288; A289; A290; A291; A292; A293; A294; A295; A296; A297; A298; A299; A300; A301; A302; A303; A304; A305; A306; A307; A308; A309; A310; A311; A312; A313; A314; A315; A316; A317; A318; A319; A320; A321; A322; A323; A324; A325; A326; A327; A328; A329; A330; A331; A332; A333; A334; A335; A336; A337; A338; A339; A340; A341; A342; A343; A344; A345; A346; A347; A348; A349; A350; A351; A352; A353; A354; A355; A356; A357; A358; A359; A360; A361; A362; A363; A364; A365; A366; A367; A368; A369; A370; A371; A372; A373; A374; A375; A376; A377; A378; A379; A380; A381; A382; A383; A384; A385; A386; A387; A388; A389; A390; A391; A392; A393; A394; A395; A396; A397; A398; A399; A400; A401; A402; A403; A404; A405; A406; A407; A408; A409; A410; A411; A412; A413; A414; A415; A416; A417; A418; A419; A420; A421; A422; A423; A424; A425; A426; A427; A428; A429; A430; A431; A432; A433; A434; A435; A436; A437; A438; A439; A440; A441; A442; A443; A444; A445; A446; A447; A448; A449; A450; A451; A452; A453; A454; A455; A456; A457; A458; A459; A460; A461; A462; A463; A464; A465; A466; A467; A468; A469; A470; A471; A472; A473; A474; A475; A476; A477; A478; A479; A480; A481; A482; A483; A484; A485; A486; A487; A488; A489; A490; A491; A492; A493; A494; A495; A496; A497; A498; A499; A500; A501";
run;
I'm guessing there's a much easier way to get to the desired end result, if only we knew why you wanted such a long and unwieldy string of text, and how you were going to use it.
Nevertheless, the answer to your direct question
Step 1: extract the first 200 characters (use the SUBSTR function)
Step 2: eliminate the last "word", any characters after the last semicolon (Use the SCAN() function)
Step 3: now the string is possibly less than 200 characters so determine it's length, lets say 197 characters (use the LENGTH() function)
Step 4: starting at the next position, let's say position 198, and extract the next 200 characters
Step 5: go to step 2
Hi @1239 ,
maybe like that:
data want;
set test;
array v[20] $ 200 var1-var20; /* 20 - to be adjusted*/
n = 0;
start = 1;
do i = 200 to max(length(var),200) by 200;
x = char(var,i);
do while(x ne ";");
i + (-1);
x = char(var,i);
end;
n+1;
v[n]=substr(var,start,i-start+1);
i+1;
start = i;
end;
n+1;
v[n]=substr(var,start);
/* test lenghts */
do i = 1 to dim(v);
n = lengthn(v[i]);
put "lengthn(v[" i +(-1) "])=" n ", " @;
end;
run;
All the best
Bart
@1239 wrote:
The below is the sample data. I want to split variables for every 200 characters however it should be end by last delimiter less than 200 meaningfully. I have attached the desired output for easy reference.
Variables should split like Var1, Var2, Var3, so on...
Please help me on how to achieve this requirement and let me know if any further information is required.
data test; var = "A1; A2; A3; A4; A5; A6; A7; A8; A9; A10; A11; A12; A13; A14; A15; A16; A17; A18; A19; A20; A21; A22; A23; A24; A25; A26; A27; A28; A29; A30; A31; A32; A33; A34; A35; A36; A37; A38; A39; A40; A41; A42; A43; A44; A45; A46; A47; A48; A49; A50; A51; A52; A53; A54; A55; A56; A57; A58; A59; A60; A61; A62; A63; A64; A65; A66; A67; A68; A69; A70; A71; A72; A73; A74; A75; A76; A77; A78; A79; A80; A81; A82; A83; A84; A85; A86; A87; A88; A89; A90; A91; A92; A93; A94; A95; A96; A97; A98; A99; A100; A101; A102; A103; A104; A105; A106; A107; A108; A109; A110; A111; A112; A113; A114; A115; A116; A117; A118; A119; A120; A121; A122; A123; A124; A125; A126; A127; A128; A129; A130; A131; A132; A133; A134; A135; A136; A137; A138; A139; A140; A141; A142; A143; A144; A145; A146; A147; A148; A149; A150; A151; A152; A153; A154; A155; A156; A157; A158; A159; A160; A161; A162; A163; A164; A165; A166; A167; A168; A169; A170; A171; A172; A173; A174; A175; A176; A177; A178; A179; A180; A181; A182; A183; A184; A185; A186; A187; A188; A189; A190; A191; A192; A193; A194; A195; A196; A197; A198; A199; A200; A201; A202; A203; A204; A205; A206; A207; A208; A209; A210; A211; A212; A213; A214; A215; A216; A217; A218; A219; A220; A221; A222; A223; A224; A225; A226; A227; A228; A229; A230; A231; A232; A233; A234; A235; A236; A237; A238; A239; A240; A241; A242; A243; A244; A245; A246; A247; A248; A249; A250; A251; A252; A253; A254; A255; A256; A257; A258; A259; A260; A261; A262; A263; A264; A265; A266; A267; A268; A269; A270; A271; A272; A273; A274; A275; A276; A277; A278; A279; A280; A281; A282; A283; A284; A285; A286; A287; A288; A289; A290; A291; A292; A293; A294; A295; A296; A297; A298; A299; A300; A301; A302; A303; A304; A305; A306; A307; A308; A309; A310; A311; A312; A313; A314; A315; A316; A317; A318; A319; A320; A321; A322; A323; A324; A325; A326; A327; A328; A329; A330; A331; A332; A333; A334; A335; A336; A337; A338; A339; A340; A341; A342; A343; A344; A345; A346; A347; A348; A349; A350; A351; A352; A353; A354; A355; A356; A357; A358; A359; A360; A361; A362; A363; A364; A365; A366; A367; A368; A369; A370; A371; A372; A373; A374; A375; A376; A377; A378; A379; A380; A381; A382; A383; A384; A385; A386; A387; A388; A389; A390; A391; A392; A393; A394; A395; A396; A397; A398; A399; A400; A401; A402; A403; A404; A405; A406; A407; A408; A409; A410; A411; A412; A413; A414; A415; A416; A417; A418; A419; A420; A421; A422; A423; A424; A425; A426; A427; A428; A429; A430; A431; A432; A433; A434; A435; A436; A437; A438; A439; A440; A441; A442; A443; A444; A445; A446; A447; A448; A449; A450; A451; A452; A453; A454; A455; A456; A457; A458; A459; A460; A461; A462; A463; A464; A465; A466; A467; A468; A469; A470; A471; A472; A473; A474; A475; A476; A477; A478; A479; A480; A481; A482; A483; A484; A485; A486; A487; A488; A489; A490; A491; A492; A493; A494; A495; A496; A497; A498; A499; A500; A501"; run;
Do you have a maximum known length for this variable? Or do you know how many of these variable parts you need to create?
How do you intend to use this collection of variables?
Admittedly, I'm not the best with regex/prx (I'm sure someone can help clean that part up)...
but my idea is to build out the variable name into 5-char pieces [i.e. A###;] and then, since 200 is divisible by 5, the splitting becomes more predictable:
data have;
length var newvar $3006.;
var = "A1; A2; A3; A4; A5; A6; A7; A8; A9; A10; A11; A12; A13; A14; A15; A16; A17; A18; A19; A20; A21; A22; A23; A24; A25; A26; A27; A28; A29; A30; A31; A32; A33; A34; A35; A36; A37; A38; A39; A40; A41; A42; A43; A44; A45; A46; A47; A48; A49; A50; A51; A52; A53; A54; A55; A56; A57; A58; A59; A60; A61; A62; A63; A64; A65; A66; A67; A68; A69; A70; A71; A72; A73; A74; A75; A76; A77; A78; A79; A80; A81; A82; A83; A84; A85; A86; A87; A88; A89; A90; A91; A92; A93; A94; A95; A96; A97; A98; A99; A100; A101; A102; A103; A104; A105; A106; A107; A108; A109; A110; A111; A112; A113; A114; A115; A116; A117; A118; A119; A120; A121; A122; A123; A124; A125; A126; A127; A128; A129; A130; A131; A132; A133; A134; A135; A136; A137; A138; A139; A140; A141; A142; A143; A144; A145; A146; A147; A148; A149; A150; A151; A152; A153; A154; A155; A156; A157; A158; A159; A160; A161; A162; A163; A164; A165; A166; A167; A168; A169; A170; A171; A172; A173; A174; A175; A176; A177; A178; A179; A180; A181; A182; A183; A184; A185; A186; A187; A188; A189; A190; A191; A192; A193; A194; A195; A196; A197; A198; A199; A200; A201; A202; A203; A204; A205; A206; A207; A208; A209; A210; A211; A212; A213; A214; A215; A216; A217; A218; A219; A220; A221; A222; A223; A224; A225; A226; A227; A228; A229; A230; A231; A232; A233; A234; A235; A236; A237; A238; A239; A240; A241; A242; A243; A244; A245; A246; A247; A248; A249; A250; A251; A252; A253; A254; A255; A256; A257; A258; A259; A260; A261; A262; A263; A264; A265; A266; A267; A268; A269; A270; A271; A272; A273; A274; A275; A276; A277; A278; A279; A280; A281; A282; A283; A284; A285; A286; A287; A288; A289; A290; A291; A292; A293; A294; A295; A296; A297; A298; A299; A300; A301; A302; A303; A304; A305; A306; A307; A308; A309; A310; A311; A312; A313; A314; A315; A316; A317; A318; A319; A320; A321; A322; A323; A324; A325; A326; A327; A328; A329; A330; A331; A332; A333; A334; A335; A336; A337; A338; A339; A340; A341; A342; A343; A344; A345; A346; A347; A348; A349; A350; A351; A352; A353; A354; A355; A356; A357; A358; A359; A360; A361; A362; A363; A364; A365; A366; A367; A368; A369; A370; A371; A372; A373; A374; A375; A376; A377; A378; A379; A380; A381; A382; A383; A384; A385; A386; A387; A388; A389; A390; A391; A392; A393; A394; A395; A396; A397; A398; A399; A400; A401; A402; A403; A404; A405; A406; A407; A408; A409; A410; A411; A412; A413; A414; A415; A416; A417; A418; A419; A420; A421; A422; A423; A424; A425; A426; A427; A428; A429; A430; A431; A432; A433; A434; A435; A436; A437; A438; A439; A440; A441; A442; A443; A444; A445; A446; A447; A448; A449; A450; A451; A452; A453; A454; A455; A456; A457; A458; A459; A460; A461; A462; A463; A464; A465; A466; A467; A468; A469; A470; A471; A472; A473; A474; A475; A476; A477; A478; A479; A480; A481; A482; A483; A484; A485; A486; A487; A488; A489; A490; A491; A492; A493; A494; A495; A496; A497; A498; A499; A500; A501";
newvar = compress(prxchange('s/(?<=A)(\d\d)(?!\d)/0$1/',-1,prxchange('s/(?<=A)(\d)(?!\d)/0$1/',-1,strip(var))));
drop var;
run;
data want;
set have;
length var1-var13 $200.;
array var(13) $;
do i=1 to dim(var);
var[i]=substr(newvar,1+200*(i-1),1+200*i);
end;
drop i newvar;
run;
proc print data=want;
run;
-unison
I would create a temporary file containing all of the split combinations, then use proc transpose to combine them into the desired variables. e.g.:
data test;
var = "A1; A2; A3; A4; A5; A6; A7; A8; A9; A10; A11; A12; A13; A14; A15; A16; A17; A18; A19; A20; A21; A22; A23; A24; A25; A26; A27; A28; A29; A30; A31; A32; A33; A34; A35; A36; A37; A38; A39; A40; A41; A42; A43; A44; A45; A46; A47; A48; A49; A50; A51; A52; A53; A54; A55; A56; A57; A58; A59; A60; A61; A62; A63; A64; A65; A66; A67; A68; A69; A70; A71; A72; A73; A74; A75; A76; A77; A78; A79; A80; A81; A82; A83; A84; A85; A86; A87; A88; A89; A90; A91; A92; A93; A94; A95; A96; A97; A98; A99; A100; A101; A102; A103; A104; A105; A106; A107; A108; A109; A110; A111; A112; A113; A114; A115; A116; A117; A118; A119; A120; A121; A122; A123; A124; A125; A126; A127; A128; A129; A130; A131; A132; A133; A134; A135; A136; A137; A138; A139; A140; A141; A142; A143; A144; A145; A146; A147; A148; A149; A150; A151; A152; A153; A154; A155; A156; A157; A158; A159; A160; A161; A162; A163; A164; A165; A166; A167; A168; A169; A170; A171; A172; A173; A174; A175; A176; A177; A178; A179; A180; A181; A182; A183; A184; A185; A186; A187; A188; A189; A190; A191; A192; A193; A194; A195; A196; A197; A198; A199; A200; A201; A202; A203; A204; A205; A206; A207; A208; A209; A210; A211; A212; A213; A214; A215; A216; A217; A218; A219; A220; A221; A222; A223; A224; A225; A226; A227; A228; A229; A230; A231; A232; A233; A234; A235; A236; A237; A238; A239; A240; A241; A242; A243; A244; A245; A246; A247; A248; A249; A250; A251; A252; A253; A254; A255; A256; A257; A258; A259; A260; A261; A262; A263; A264; A265; A266; A267; A268; A269; A270; A271; A272; A273; A274; A275; A276; A277; A278; A279; A280; A281; A282; A283; A284; A285; A286; A287; A288; A289; A290; A291; A292; A293; A294; A295; A296; A297; A298; A299; A300; A301; A302; A303; A304; A305; A306; A307; A308; A309; A310; A311; A312; A313; A314; A315; A316; A317; A318; A319; A320; A321; A322; A323; A324; A325; A326; A327; A328; A329; A330; A331; A332; A333; A334; A335; A336; A337; A338; A339; A340; A341; A342; A343; A344; A345; A346; A347; A348; A349; A350; A351; A352; A353; A354; A355; A356; A357; A358; A359; A360; A361; A362; A363; A364; A365; A366; A367; A368; A369; A370; A371; A372; A373; A374; A375; A376; A377; A378; A379; A380; A381; A382; A383; A384; A385; A386; A387; A388; A389; A390; A391; A392; A393; A394; A395; A396; A397; A398; A399; A400; A401; A402; A403; A404; A405; A406; A407; A408; A409; A410; A411; A412; A413; A414; A415; A416; A417; A418; A419; A420; A421; A422; A423; A424; A425; A426; A427; A428; A429; A430; A431; A432; A433; A434; A435; A436; A437; A438; A439; A440; A441; A442; A443; A444; A445; A446; A447; A448; A449; A450; A451; A452; A453; A454; A455; A456; A457; A458; A459; A460; A461; A462; A463; A464; A465; A466; A467; A468; A469; A470; A471; A472; A473; A474; A475; A476; A477; A478; A479; A480; A481; A482; A483; A484; A485; A486; A487; A488; A489; A490; A491; A492; A493; A494; A495; A496; A497; A498; A499; A500; A501";
output;
output;
run;
data need (drop=_:);
set test;
recnum=_n_;
_var=var;
_end=1;
do while (_end gt 0);
if length(strip(_var)) lt 200 then do;
var=_var;
_end=0;
end;
else do;
_end=findc(_var,';',-199);
var=substr(_var,1,_end);
_var=strip(substr(_var,_end+1));
end;
output;
end;
run;
proc transpose data=need out=want (drop=_:) prefix=var;
var var;
by recnum;
run;
Art, CEO, AnalystFinder.com
Hi @1239
A simple solution is to split the input string in single variables, concatenate to an output string until the length is exhausted, then output and start a new output string and so on,..
data test;
var = "A1; A2; A3; A4; A5; A6; A7; A8; A9; A10; A11; A12; A13; A14; A15; A16; A17; A18; A19; A20; A21; A22; A23; A24; A25; A26; A27; A28; A29; A30; A31; A32; A33; A34; A35; A36; A37; A38; A39; A40; A41; A42; A43; A44; A45; A46; A47; A48; A49; A50; A51; A52; A53; A54; A55; A56; A57; A58; A59; A60; A61; A62; A63; A64; A65; A66; A67; A68; A69; A70; A71; A72; A73; A74; A75; A76; A77; A78; A79; A80; A81; A82; A83; A84; A85; A86; A87; A88; A89; A90; A91; A92; A93; A94; A95; A96; A97; A98; A99; A100; A101; A102; A103; A104; A105; A106; A107; A108; A109; A110; A111; A112; A113; A114; A115; A116; A117; A118; A119; A120; A121; A122; A123; A124; A125; A126; A127; A128; A129; A130; A131; A132; A133; A134; A135; A136; A137; A138; A139; A140; A141; A142; A143; A144; A145; A146; A147; A148; A149; A150; A151; A152; A153; A154; A155; A156; A157; A158; A159; A160; A161; A162; A163; A164; A165; A166; A167; A168; A169; A170; A171; A172; A173; A174; A175; A176; A177; A178; A179; A180; A181; A182; A183; A184; A185; A186; A187; A188; A189; A190; A191; A192; A193; A194; A195; A196; A197; A198; A199; A200; A201; A202; A203; A204; A205; A206; A207; A208; A209; A210; A211; A212; A213; A214; A215; A216; A217; A218; A219; A220; A221; A222; A223; A224; A225; A226; A227; A228; A229; A230; A231; A232; A233; A234; A235; A236; A237; A238; A239; A240; A241; A242; A243; A244; A245; A246; A247; A248; A249; A250; A251; A252; A253; A254; A255; A256; A257; A258; A259; A260; A261; A262; A263; A264; A265; A266; A267; A268; A269; A270; A271; A272; A273; A274; A275; A276; A277; A278; A279; A280; A281; A282; A283; A284; A285; A286; A287; A288; A289; A290; A291; A292; A293; A294; A295; A296; A297; A298; A299; A300; A301; A302; A303; A304; A305; A306; A307; A308; A309; A310; A311; A312; A313; A314; A315; A316; A317; A318; A319; A320; A321; A322; A323; A324; A325; A326; A327; A328; A329; A330; A331; A332; A333; A334; A335; A336; A337; A338; A339; A340; A341; A342; A343; A344; A345; A346; A347; A348; A349; A350; A351; A352; A353; A354; A355; A356; A357; A358; A359; A360; A361; A362; A363; A364; A365; A366; A367; A368; A369; A370; A371; A372; A373; A374; A375; A376; A377; A378; A379; A380; A381; A382; A383; A384; A385; A386; A387; A388; A389; A390; A391; A392; A393; A394; A395; A396; A397; A398; A399; A400; A401; A402; A403; A404; A405; A406; A407; A408; A409; A410; A411; A412; A413; A414; A415; A416; A417; A418; A419; A420; A421; A422; A423; A424; A425; A426; A427; A428; A429; A430; A431; A432; A433; A434; A435; A436; A437; A438; A439; A440; A441; A442; A443; A444; A445; A446; A447; A448; A449; A450; A451; A452; A453; A454; A455; A456; A457; A458; A459; A460; A461; A462; A463; A464; A465; A466; A467; A468; A469; A470; A471; A472; A473; A474; A475; A476; A477; A478; A479; A480; A481; A482; A483; A484; A485; A486; A487; A488; A489; A490; A491; A492; A493; A494; A495; A496; A497; A498; A499; A500; A501";
run;
options noquotelenmax;
data want (drop=var i item); set test;
length outvar $200 item $10;
outvar = '';
do until (item = '');
i + 1;
item = scan(var,i,' ');
if length(outvar) + length(item) + 1 <= 200 then outvar = catx(' ',outvar,item);
else do;
output;
outvar = item;
end;
end;
if outvar ne '' then output;
run;
regards
Erik
This should work:
data want;
set test;
array out(*) $200 var1-var20;
_I_=1;
do _N_=1 to dim(out);
out(_N_)=substr(var,_I_);
if _I_+200>length(var) then
leave;
if substr(out(_N_),200)=' ' then
_I_+200;
else if substr(var,_I_+200,1)=' ' then
_I_+201;
else do;
_L_=200-length(scan(out(_N_),-1,' '));
substr(out(_N_),_L_)=' ';
_I_+_L_;
end;
end;
drop var _:;
run;
Just make sure your array is long enough to accommodate all the stuff.
Hello,
data test;
length var tmp $3000;
do i=1 to 501;
call catx(' ',var,cats('A',i,';'));
end;
tmp=prxchange('s/(.{1,199}; *)/${1}#/',-1,var);
call symputx('n',countw(tmp,'#'));
run;
data test;
set test;
array vars $200. var1-var&n.;
do i=1 to &n.;
vars(i)=scan(tmp,i,'#');
end;
keep var1-var&n.;
run;
Edit :
A variant with a single data step but the number of variables is guessed instead of computed.
%let n=50; /* Array size */
data test;
set test;
length tmp $3000;
array vars $200. var1-var&n.;
tmp=prxchange('s/(.{1,199}; *)/${1}#/',-1,var);
nvars=countw(tmp,'#');
if nvars>dim(vars) then put "Warning: insufficient array size";
do i=1 to nvars until (i=dim(vars));
vars(i)=scan(tmp,i,'#');
end;
keep var1-var&n.;
run;
So you have one long list of "words" and you want to split into multiple shorter lists.
So scan the list for each word and if it will fit add it to the current new variable, otherwise add it to the next new variable.
data want ;
set have ;
array new $200 var1-var10 ;
index=1;
do i=1 to countw(var,';');
length word $200;
word=scan(var,i,';');
if length(word)+length(var[index])+1 > 200 then index=index+1;
new[index]=catx(';',new[index],word);
end;
run;
Note that if any individual work is actually longer than 200 characters this cannot work.
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.