substring

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

substring

drfg2008
We have a string variable "combinationLenghts" and try to get out the numbers as separate numerical variables. All numbers are separated by comma.

Example

DATA LIST FREE / combinationLengths (A40).
BEGIN DATA.
"9,10,11"
"6,7"
"2,3,4"
"2,6,7,8,9".
END DATA.
EXECUTE.

The result should be 5 (can be more) variables containing only the numbers or blanks.
Example:

v1 v2 v3 v4 v5
9  10  11  .   .
6   7    .   .   .
2   3    4  .   .
2   6    7  8   9

Tried a lot with substrings but my results are not only awkward but also totally unacceptable.
Should not contain Python, if possible.
Thanks for some help.
Dr. Frank Gaeth

Reply | Threaded
Open this post in threaded view
|

Re: substring

Andy W
Here is my first stab, I doubt I'll win any awards for prettiness. Look forward to seeing better solutions (you could export to plain text and import using DATA LIST - but that is pretty unappealing for alot of situations).

*************************************.
DATA LIST FREE / combinationLengths (A40).
BEGIN DATA.
"9,10,11"
"6,7"
"2,3,4"
"2,6,7,8,9"
END DATA.

VECTOR Nums (10). /*Need to know max #*/
COMPUTE #i = 0.
STRING #a (A40). /* Assuming you know string width as well */
COMPUTE #a = combinationLengths.
COMPUTE #NCom = CHAR.INDEX(#a,",").
LOOP.
COMPUTE #i = #i + 1.
COMPUTE #NCom = CHAR.INDEX(#a,",").
IF #NCom > 0 Nums(#i) = NUMBER(CHAR.SUBSTR(#a,1,#Ncom-1),F3.0). /* always integers? */
IF #Ncom > 0 #a = CHAR.SUBSTR(#a,#Ncom+1).
END LOOP IF #Ncom = 0.
COMPUTE Nums(#i) = NUMBER(#a,F3.0).
EXECUTE.
*************************************.
Andy W
apwheele@gmail.com
http://andrewpwheeler.wordpress.com/
Reply | Threaded
Open this post in threaded view
|

Re: substring

David Marso
Administrator
My old friend SADAMU ;-)
How about a macro you can stash in your Utilities .

DATA LIST FREE / combinationLengths (A40).
BEGIN DATA.
"9,10,11"
"6,7"
"2,3,4"
"2,6,7,8,9"
END DATA.

DEFINE Split
  ( Var !TOKENS(1)
 / Root !TOKENS(1) !DEFAULT (Num)
 /Delim !TOKENS(1) !DEFAULT(',')
 / LenX !TOKENS(1) !DEFAULT (40)
 /  Max !TOKENS(1) !DEFAULT (10)
 /  Fmt !TOKENS(1) !DEFAULT (3)).
!LET !List=!CONCAT(!Root,'01 TO ',!Root,!Max)
STRING !List(!CONCAT(A,!Fmt)).
VECTOR !Root = !List .
COMPUTE #i = 1.
STRING #a (!CONCAT(A,!LenX)).
COMPUTE #a = !Var.
LOOP.
+  COMPUTE #NCom = CHAR.INDEX(#a,!QUOTE(!Delim)).
+  DO IF (#NCom GT 0).
+    COMPUTE !Root(#i) =CHAR.SUBSTR(#a,1,#Ncom-1).
+    COMPUTE #a = CHAR.SUBSTR(#a,#Ncom+1).
+    COMPUTE #i = #i + 1.
+  END IF.
END LOOP IF #Ncom EQ 0.
COMPUTE !Root(#i) = #a.

ALTER TYPE !List (!CONCAT(F,!Fmt)).
EXECUTE.
!ENDDEFINE.
SET MPRINT ON PRINTBACK ON.

/* Default arguments assumed */.
Split Var=combinationLengths .

/* Explicit call */.
SPLIT Var=combinationLengths  Root =Num Delim =, LenX =40 Max=10 Fmt =3.

----------------------------

Andy W wrote
Here is my first stab, I doubt I'll win any awards for prettiness. Look forward to seeing better solutions (you could export to plain text and import using DATA LIST - but that is pretty unappealing for alot of situations).

*************************************.
DATA LIST FREE / combinationLengths (A40).
BEGIN DATA.
"9,10,11"
"6,7"
"2,3,4"
"2,6,7,8,9"
END DATA.

VECTOR Nums (10). /*Need to know max #*/
COMPUTE #i = 0.
STRING #a (A40). /* Assuming you know string width as well */
COMPUTE #a = combinationLengths.
COMPUTE #NCom = CHAR.INDEX(#a,",").
LOOP.
COMPUTE #i = #i + 1.
COMPUTE #NCom = CHAR.INDEX(#a,",").
IF #NCom > 0 Nums(#i) = NUMBER(CHAR.SUBSTR(#a,1,#Ncom-1),F3.0). /* always integers? */
IF #Ncom > 0 #a = CHAR.SUBSTR(#a,#Ncom+1).
END LOOP IF #Ncom = 0.
COMPUTE Nums(#i) = NUMBER(#a,F3.0).
EXECUTE.
*************************************.
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: substring

drfg2008
In reply to this post by Andy W
works great, thanks!
Dr. Frank Gaeth

Reply | Threaded
Open this post in threaded view
|

Re: substring

Andy W
In reply to this post by David Marso
Nice - For more general use I may be sneaky and set the default Delim to be an empty space, so you don't need to make special arrangements to split a space delimited string.

Also to make it work for non-integer formats, you can just change

STRING !List(!CONCAT(A,!Fmt)).

To

STRING !List(!CONCAT(A,!LenX)).

(I don't see much harm in this, making the vector of strings long at first and then ALTER TYPE later on.) SADAMU?
Andy W
apwheele@gmail.com
http://andrewpwheeler.wordpress.com/
Reply | Threaded
Open this post in threaded view
|

Re: substring

David Marso
Administrator
SADAMU (Slice and Dice and Mop Up).  But that method/code is probably as ancient as 1995 or so ;-)
http://spssx-discussion.1045642.n5.nabble.com/Fw-Help-with-selecting-records-reply-to-David-Marso-td4640982.html#a4641309
One could set the !defaults to whatever falls under the most common circumstance.

Andy W wrote
Nice - For more general use I may be sneaky and set the default Delim to be an empty space, so you don't need to make special arrangements to split a space delimited string.

Also to make it work for non-integer formats, you can just change

STRING !List(!CONCAT(A,!Fmt)).

To

STRING !List(!CONCAT(A,!LenX)).

(I don't see much harm in this, making the vector of strings long at first and then ALTER TYPE later on.) SADAMU?
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"