Add a decimal point

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

Add a decimal point

vstirkey

Hi, I have a variable that contains 5 character strings. I would like to add a decimal point so that each value reads xxx.xx instead of xxxxx. I have changed the width to accommodate the change. Does anyone know how I can write syntax to create this change? Would this be a search and replace function?

 

 

Vicki L. Stirkey

OMHSAS l Bureau of Quality Management and Data Review

112 East Azalea Drive l Hbg PA  17110

Phone: 717.705.8198 l Fax: 717.772.6737

www.dpw.state.pa.us

 

Reply | Threaded
Open this post in threaded view
|

adding decimal point to a variable

vstirkey

Hi, I have a variable that contains 5 character strings. I would like to add a decimal point so that each value reads xxx.xx instead of xxxxx. I have changed the width to accommodate the change. Does anyone know how I can write syntax to create this change?

 

Vicki L. Stirkey

OMHSAS l Bureau of Quality Management and Data Review

112 East Azalea Drive l Hbg PA  17110

Phone: 717.705.8198 l Fax: 717.772.6737

www.dpw.state.pa.us

 

Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Art Kendall
In reply to this post by vstirkey
open a new instance of SPSS.
Paste the syntax below into a syntax window.
Run it.

Is that what you want?

data list list/mystring (a5).
begin data
12345
abcde
#####
+++++
end data.
string newstring(a6).
compute newstring = concat(
   substr(mystring,1,3),
   ".",
   substr(mystring,4,2)).
list.


Art Kendall
Social Research Consultants
On 11/27/2013 8:00 AM, Stirkey, Vicki-2 [via SPSSX Discussion] wrote:

Hi, I have a variable that contains 5 character strings. I would like to add a decimal point so that each value reads xxx.xx instead of xxxxx. I have changed the width to accommodate the change. Does anyone know how I can write syntax to create this change? Would this be a search and replace function?

 

 

Vicki L. Stirkey

OMHSAS l Bureau of Quality Management and Data Review

112 East Azalea Drive l Hbg PA  17110

Phone: 717.705.8198 l Fax: 717.772.6737

www.dpw.state.pa.us

 




If you reply to this email, your message will be added to the discussion below:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331.html
To start a new topic under SPSSX Discussion, email [hidden email]
To unsubscribe from SPSSX Discussion, click here.
NAML

Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

David Marso
Administrator
I would probably exploit the SUBSTR assignment feature ;-)

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.
STRING newstring (A6).
COMPUTE newstring=mystring.
COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).
LIST.

mystring newstring
 
12345    123.45
abcde    abc.de
#####    ###.##
+++++    +++.++
 
 
Number of cases read:  4    Number of cases listed:  4

Art Kendall wrote
open a new instance of
        SPSS.
        Paste the syntax below into a syntax window.
        Run it.
       
        Is that what you want?
     
      data list list/mystring (a5).
        begin data
        12345
        abcde
        #####
        +++++
        end data.
        string newstring(a6).
        compute newstring = concat(
           substr(mystring,1,3),
           ".",
           substr(mystring,4,2)).
        list.
       
       
     
      Art Kendall
Social Research Consultants
      On 11/27/2013 8:00 AM, Stirkey, Vicki-2 [via SPSSX Discussion]
      wrote:
   
   
     
     
     
     
        Hi, I have a variable that contains 5
          character strings. I would like to add a decimal point so that
          each value reads xxx.xx instead of xxxxx. I have changed the
          width to accommodate the change. Does anyone know how I can
          write syntax to create this change? Would this be a search and
          replace function?
         
         
        Vicki
            L. Stirkey
        OMHSAS
          l
            Bureau
            of Quality Management and Data Review
        112
            East Azalea Drive l
            Hbg
            PA  17110
        Phone:
            717.705.8198 l
            Fax:
            717.772.6737
        www.dpw.state.pa.us
         
     
     
     
     
     
        If you reply to this email, your
          message will be added to the discussion below:
        http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331.html 
     
     
        To start a new topic under SPSSX Discussion, email
        [hidden email] 
        To unsubscribe from SPSSX Discussion, click
          here .
        NAML
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: Add a decimal point

Bruce Weaver
Administrator
When I saw that David was using SUBSTR on the left side of that COMPUTE and CHAR.SUBSTR on the right side, I decided to try the following variation on his syntax.

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.

STRING newstring1 to newstring3 (A6).
DO REPEAT new = newstring1 to newstring3.
- COMPUTE new=mystring.
END REPEAT.

COMPUTE SUBSTR(newstring1,4) = CONCAT(".",CHAR.SUBSTR(newstring1,4)).
COMPUTE SUBSTR(newstring2,4) = CONCAT(".",SUBSTR(newstring2,4)).
COMPUTE CHAR.SUBSTR(newstring3,4) = CONCAT(".",CHAR.SUBSTR(newstring3,4)).

LIST.

Output:
mystring newstring1 newstring2 newstring3 
 
12345    123.45     123.45     12345 
abcde    abc.de     abc.de     abcde 
#####    ###.##     ###.##     ##### 
+++++    +++.++     +++.++     +++++ 
  
Number of cases read:  4    Number of cases listed:  4


Note that you can use CHAR.SUBSTR or SUBSTR on the right side of the COMPUTE, but must use SUBSTR on the left side.  Using CHAR.SUBSTR on the left generates an error.


David Marso wrote
I would probably exploit the SUBSTR assignment feature ;-)

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.
STRING newstring (A6).
COMPUTE newstring=mystring.
COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).
LIST.

mystring newstring
 
12345    123.45
abcde    abc.de
#####    ###.##
+++++    +++.++
 
 
Number of cases read:  4    Number of cases listed:  4

Art Kendall wrote
open a new instance of
        SPSS.
        Paste the syntax below into a syntax window.
        Run it.
       
        Is that what you want?
     
      data list list/mystring (a5).
        begin data
        12345
        abcde
        #####
        +++++
        end data.
        string newstring(a6).
        compute newstring = concat(
           substr(mystring,1,3),
           ".",
           substr(mystring,4,2)).
        list.
       
       
     
      Art Kendall
Social Research Consultants
      On 11/27/2013 8:00 AM, Stirkey, Vicki-2 [via SPSSX Discussion]
      wrote:
   
   
     
     
     
     
        Hi, I have a variable that contains 5
          character strings. I would like to add a decimal point so that
          each value reads xxx.xx instead of xxxxx. I have changed the
          width to accommodate the change. Does anyone know how I can
          write syntax to create this change? Would this be a search and
          replace function?
         
         
        Vicki
            L. Stirkey
        OMHSAS
          l
            Bureau
            of Quality Management and Data Review
        112
            East Azalea Drive l
            Hbg
            PA  17110
        Phone:
            717.705.8198 l
            Fax:
            717.772.6737
        www.dpw.state.pa.us
         
     
     
     
     
     
        If you reply to this email, your
          message will be added to the discussion below:
        http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331.html 
     
     
        To start a new topic under SPSSX Discussion, email
        [hidden email] 
        To unsubscribe from SPSSX Discussion, click
          here .
        NAML
--
Bruce Weaver
bweaver@lakeheadu.ca
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

PLEASE NOTE THE FOLLOWING: 
1. My Hotmail account is not monitored regularly. To send me an e-mail, please use the address shown above.
2. The SPSSX Discussion forum on Nabble is no longer linked to the SPSSX-L listserv administered by UGA (https://listserv.uga.edu/).
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

David Marso
Administrator
"When I saw that David was using SUBSTR on the left side of that COMPUTE and CHAR.SUBSTR on the right side, I decided to try the following variation on his syntax."

From the FM ;-)  It would be nice if the LEFT side functionality were made more explicit in the documenttion.  Most people don't even know it is permitted.  I never knew until I accidently did it and it worked ;-)

CHAR.SUBSTR. CHAR.SUBSTR(strexpr,pos[,length]). String. Returns the substring beginning at character position pos of strexpr. The optional third argument represents the number of characters in the substring. If the optional argument length is omitted, returns the substring beginning at character position pos of strexpr and running to the end of strexpr. For example CHAR.SUBSTR('abcd', 2) returns 'bcd' and CHAR.SUBSTR('abcd', 2, 2) returns 'bc'. (Note: Use the SUBSTR function instead of CHAR.SUBSTR if you want to use the function on the left side of an equals sign to replace a substring.)

Probably some weird Unicode issue?  Maybe Jon(noH) will elaborate for benefit of the class?

Bruce Weaver wrote
When I saw that David was using SUBSTR on the left side of that COMPUTE and CHAR.SUBSTR on the right side, I decided to try the following variation on his syntax.

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.

STRING newstring1 to newstring3 (A6).
DO REPEAT new = newstring1 to newstring3.
- COMPUTE new=mystring.
END REPEAT.

COMPUTE SUBSTR(newstring1,4) = CONCAT(".",CHAR.SUBSTR(newstring1,4)).
COMPUTE SUBSTR(newstring2,4) = CONCAT(".",SUBSTR(newstring2,4)).
COMPUTE CHAR.SUBSTR(newstring3,4) = CONCAT(".",CHAR.SUBSTR(newstring3,4)).

LIST.

Output:
mystring newstring1 newstring2 newstring3 
 
12345    123.45     123.45     12345 
abcde    abc.de     abc.de     abcde 
#####    ###.##     ###.##     ##### 
+++++    +++.++     +++.++     +++++ 
  
Number of cases read:  4    Number of cases listed:  4


Note that you can use CHAR.SUBSTR or SUBSTR on the right side of the COMPUTE, but must use SUBSTR on the left side.  Using CHAR.SUBSTR on the left generates an error.


David Marso wrote
I would probably exploit the SUBSTR assignment feature ;-)

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.
STRING newstring (A6).
COMPUTE newstring=mystring.
COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).
LIST.

mystring newstring
 
12345    123.45
abcde    abc.de
#####    ###.##
+++++    +++.++
 
 
Number of cases read:  4    Number of cases listed:  4
<SNIP>
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: Add a decimal point

Jon K Peck
In reply to this post by David Marso
I would recommend against using left-hand-side SUBSTR, because in general it will not work in Unicode mode, where characters can be variable length.  If everything is plain 7-bit ascii, it still works in that mode, but you are  building in an unnecessary constraint on the generality of the code.


Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        David Marso <[hidden email]>
To:        [hidden email],
Date:        11/27/2013 09:00 AM
Subject:        Re: [SPSSX-L] Add a decimal point
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




I would probably exploit the SUBSTR assignment feature ;-)

DATA LIST LIST / mystring (a5).
BEGIN DATA
12345
abcde
#####
+++++
END DATA.
STRING newstring (A6).
COMPUTE newstring=mystring.
COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).
LIST.

mystring newstring

12345    123.45
abcde    abc.de
#####    ###.##
+++++    +++.++


Number of cases read:  4    Number of cases listed:  4


Art Kendall wrote
> open a new instance of
>         SPSS.
>         Paste the syntax below into a syntax window.
>         Run it.
>
>         Is that what you want?
>
>       data list list/mystring (a5).
>         begin data
>         12345
>         abcde
>         #####
>         +++++
>         end data.
>         string newstring(a6).
>         compute newstring = concat(
>         &nbsp;&nbsp; substr(mystring,1,3),
>         &nbsp;&nbsp; ".",
>         &nbsp;&nbsp; substr(mystring,4,2)).
>         list.
>
>
>
>       Art Kendall
> Social Research Consultants
>       On 11/27/2013 8:00 AM, Stirkey, Vicki-2 [via SPSSX Discussion]
>       wrote:
>
>
>
>
>
>
>         Hi, I have a variable that contains 5
>           character strings. I would like to add a decimal point so that
>           each value reads xxx.xx instead of xxxxx. I have changed the
>           width to accommodate the change. Does anyone know how I can
>           write syntax to create this change? Would this be a search and
>           replace function?
>         &nbsp;
>         &nbsp;
>         Vicki
>             L. Stirkey
>         OMHSAS
>           l
>             Bureau
>             of Quality Management and Data Review
>         112
>             East Azalea Drive l
>             Hbg
>             PA&nbsp; 17110
>         Phone:
>             717.705.8198 l
>             Fax:
>             717.772.6737
>        
www.dpw.state.pa.us
>         &nbsp;
>
>
>
>
>
>         If you reply to this email, your
>           message will be added to the discussion below:
>
>
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331.html
>
>
>         To start a new topic under SPSSX Discussion, email
>

> ml-node+s1045642n1068821h68@.nabble

>
>         To unsubscribe from SPSSX Discussion, click
>           here .
>         NAML





-----
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?"
--
View this message in context:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331p5723342.html
Sent from the SPSSX Discussion mailing list archive at Nabble.com.

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD


Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Ruben Geert van den Berg
I think it's really weird that there's SUBSTR and CHAR.SUBSTR (which does what one would expect from SUBSTR) in the first place.

Given a multiple-byte character string, who on earth would ever want to extract the first byte instead of the first character?!

Or am I missing something here?
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Jon K Peck
The original string functions date back to the simple era when a character was a byte, and all the position parameters were interpreted in bytes.  Since you can't tell by code inspection in some cases whether bytes or characters were meant, we introduced a new set of char.* functions when Statistics began to support Unicode in V16 so that existing code that meant bytes would not break.  The difference was only relevant for the double-byte characters used in the large Asian character sets.  For example, the length and index functions return the length or position in a string in bytes while char.length and char.index operate in character units.

Since, the char.* functions all work on character positions, not bytes, they are impervious to Unicode vs code page operation.  Where there isn't a char.* equivalent to an old string function, the distinction does not matter, or, for a few functions that were designed specifically for byte operations, there would be  no use for the char equivalent.

You can see why left-hand-side substr wouldn't work well in character units, since the size of the replacement could easily be different from the size being replaced, and users can't be expected to calculate all that.

The message, is, if there is a char.* equivalent of an old function, use the char.* version, even in code page mode, since they will work the same way in both modes and they eliminate the possibility of inserting a byte sequence in the middle of another character.



Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        Ruben Geert van den Berg <[hidden email]>
To:        [hidden email],
Date:        11/27/2013 01:45 PM
Subject:        Re: [SPSSX-L] Add a decimal point
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




I think it's really weird that there's SUBSTR and CHAR.SUBSTR (which does
what one would expect from SUBSTR) in the first place.

Given a multiple-byte character string, who on earth would ever want to
extract the first byte instead of the first character?!

Or am I missing something here?



--
View this message in context:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331p5723348.html
Sent from the SPSSX Discussion mailing list archive at Nabble.com.

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD


Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

David Marso
Administrator
In reply to this post by Ruben Geert van den Berg
I would hope that it would do what I ask extract # characters.  Seems like there must be something crappy in the programming if Jon's warning is to be taken seriously.  I've been using the lefthanded SUBSTR trick for over a decade now.  I don't deal with multibyte characters and will likely continue to do so unless I land a client that insists on it.


On Wed, Nov 27, 2013 at 3:42 PM, Ruben Geert van den Berg [via SPSSX Discussion] <[hidden email]> wrote:
I think it's really weird that there's SUBSTR and CHAR.SUBSTR (which does what one would expect from SUBSTR) in the first place.

Given a multiple-byte character string, who on earth would ever want to extract the first byte instead of the first character?!

Or am I missing something here?


If you reply to this email, your message will be added to the discussion below:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331p5723348.html
To unsubscribe from Add a decimal point, click here.
NAML

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: Add a decimal point

Jon K Peck
Fixing that functionality would be quite difficult, since it would mean rewriting the entire string, which might then exceed the declared string size, and the intention would not always be clear.  We thought about that a lot when we designed the new functions.

Remember that even accented roman characters - anything not 7-bit ascii, are multibyte in Unicode.


Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        David Marso <[hidden email]>
To:        [hidden email],
Date:        11/27/2013 02:22 PM
Subject:        Re: [SPSSX-L] Add a decimal point
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




I would hope that it would do what I ask extract # characters.  Seems like there must be something crappy in the programming if Jon's warning is to be taken seriously.  I've been using the lefthanded SUBSTR trick for over a decade now.  I don't deal with multibyte characters and will likely continue to do so unless I land a client that insists on it.


On Wed, Nov 27, 2013 at 3:42 PM, Ruben Geert van den Berg [via SPSSX Discussion] <[hidden email]> wrote:
I think it's really weird that there's SUBSTR and CHAR.SUBSTR (which does what one would expect from SUBSTR) in the first place.

Given a multiple-byte character string, who on earth would ever want to extract the first byte instead of the first character?!

Or am I missing something here?



If you reply to this email, your message will be added to the discussion below:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331p5723348.html
To unsubscribe from Add a decimal point, click here.
NAML

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?"



View this message in context: Re: Add a decimal point
Sent from the
SPSSX Discussion mailing list archive at Nabble.com.
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Ruben Geert van den Berg
I see. That's why

set unicode on.

data list free/id(a1).
begin data
e
end data.

compute substring(id,1) = 'è'.
exe.

is not going to work.

The way things have been implemented now requires users to know how many bytes each of their characters take up in Unicode for setting string lengths properly. Or are they supposed to always set these as 3 times the number of characters (but not in code page mode of course) ?

Just as with "char.substr" versus "substr" and "rtrim" versus no "rtrim" I kinda feel users are bothered with too many technical details here...
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Jon K Peck
The newer string functions, being character based, eliminate the previous need to worry about bytes vs characters in string manipulation, which was an issue for Asian character sets prior to Unicode, but since strings ultimately map to storage in bytes, there is no size guaranteed to work for all possible contents other than 3 x number of characters.  If you use that rule, however, you can use ALTER TYPE (A=AMIN) or one of its expansion forms to set the optimal size.  As memory has become so plentiful, excess length is rarely an issue anymore, however.  The ultimate solution would be to support variable-length strings and eliminate the need to declare a length at all.  Unfortunately the fixed length string size is so deeply embedded in millions of lines of code, that this would be prohibitively expensive to implement.  And, of course, it could not be backwards compatible with older versions of Statistics.


Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        Ruben Geert van den Berg <[hidden email]>
To:        [hidden email],
Date:        11/28/2013 11:52 PM
Subject:        Re: [SPSSX-L] Add a decimal point
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




I see. That's why

set unicode on.

data list free/id(a1).
begin data
e
end data.

compute substring(id,1) = 'è'.
exe.

is not going to work.

The way things have been implemented now requires /users/ to know how many
bytes each of their characters take up in Unicode for setting string lengths
properly. Or are they supposed to always set these as 3 times the number of
characters (but not in code page mode of course) ?

Just as with "char.substr" versus "substr" and "rtrim" versus no "rtrim" I
kinda feel users are bothered with too many technical details here...



--
View this message in context:
http://spssx-discussion.1045642.n5.nabble.com/Add-a-decimal-point-tp5723331p5723365.html
Sent from the SPSSX Discussion mailing list archive at Nabble.com.

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD


Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Richard Ristow
In reply to this post by David Marso
At 04:22 PM 11/27/2013, David Marso wrote:

>I would hope that it would do what I ask extract #
>characters.  Seems like there must be something crappy in the
>programming if Jon's warning is to be taken seriously. I've been
>using the lefthanded SUBSTR trick for over a decade now. I don't
>deal with multibyte characters and will likely continue [not] to do
>so unless I land a client that insists on it.

Tastes vary. I use the assigning SUBSTR myself sometimes; but not
very often, and always carefully.

When you have to replace a snippet of text, especially a short one,
by another of exactly the same length, doing it with an assigning
SUBSTR can be the clearest way -- instead of

COMPUTE STRING = CONCAT(SUBSTR(STRING,1,<place before replaced text>),
                         '<replacement>',
                         SUBSTR(STRING,<place after replaced text>)).
write

COMPUTE SUBSTR(<place where replaced text starts>),<length>) = '<replacement>'.

But it's error-prone; it's easy to get careless about the SUBSTR on
the left, and the replacement text, being *exactly* the same length.
(That's why I rarely use it except when the replacement text is a
short constant value.)

David Marso's

>STRING newstring (A6).
>COMPUTE newstring=mystring.
>COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).

is a 'cute' use of the assigning substring. On the face of it, it
*doesn't* seem to meet the criterion of the replacement string being
the same length as that to be replaced: a decimal and two digits,
replacing two digits. It actually works, because the initial
declaration and assignment had previously replaced the two trailing
digits by two trailing digits and a space. But I had to look two or
three times to be sure about that. In this case, I think

STRING  newstring (A6).
COMPUTE newstring = CONCAT(CHAR.SUBSTR(mystring,1,4),
                            '.',
                            CHAR.SUBSTR(mystring,5,2)).

would be clearer.

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: Add a decimal point

Jon K Peck
And, since substitution strings often come from user data or metadata or translatable strings in the output,  how would you know you only need to deal with plain ascii?

In code page mode, except for the large Asian character sets, an errant substitution will just lead to overwriting or leaving some old characters in place, but in Unicode mode you can corrupt the character string by whacking just a part of a 2 or 3 byte character which is likely to trigger a more serious error.


Jon Peck (no "h") aka Kim
Senior Software Engineer, IBM
[hidden email]
phone: 720-342-5621




From:        Richard Ristow <[hidden email]>
To:        [hidden email],
Date:        11/30/2013 10:06 AM
Subject:        Re: [SPSSX-L] Add a decimal point
Sent by:        "SPSSX(r) Discussion" <[hidden email]>




At 04:22 PM 11/27/2013, David Marso wrote:

>I would hope that it would do what I ask extract #
>characters.  Seems like there must be something crappy in the
>programming if Jon's warning is to be taken seriously. I've been
>using the lefthanded SUBSTR trick for over a decade now. I don't
>deal with multibyte characters and will likely continue [not] to do
>so unless I land a client that insists on it.

Tastes vary. I use the assigning SUBSTR myself sometimes; but not
very often, and always carefully.

When you have to replace a snippet of text, especially a short one,
by another of exactly the same length, doing it with an assigning
SUBSTR can be the clearest way -- instead of

COMPUTE STRING = CONCAT(SUBSTR(STRING,1,<place before replaced text>),
                        '<replacement>',
                        SUBSTR(STRING,<place after replaced text>)).
write

COMPUTE SUBSTR(<place where replaced text starts>),<length>) = '<replacement>'.

But it's error-prone; it's easy to get careless about the SUBSTR on
the left, and the replacement text, being *exactly* the same length.
(That's why I rarely use it except when the replacement text is a
short constant value.)

David Marso's

>STRING newstring (A6).
>COMPUTE newstring=mystring.
>COMPUTE SUBSTR(newstring,4) = CONCAT(".",CHAR.SUBSTR(newstring,4)).

is a 'cute' use of the assigning substring. On the face of it, it
*doesn't* seem to meet the criterion of the replacement string being
the same length as that to be replaced: a decimal and two digits,
replacing two digits. It actually works, because the initial
declaration and assignment had previously replaced the two trailing
digits by two trailing digits and a space. But I had to look two or
three times to be sure about that. In this case, I think

STRING  newstring (A6).
COMPUTE newstring = CONCAT(CHAR.SUBSTR(mystring,1,4),
                           '.',
                           CHAR.SUBSTR(mystring,5,2)).

would be clearer.

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD