Creating a variable or function?

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

Creating a variable or function?

J.D. Haltigan
Struggling a bit with the following challenge:

I have two variables (numeric) that are DOBs (e.g., 1997, 1996). Let's call
these X1 and X2. I need to create an identifier variable such if X1 OR X2 is
EQUAL to the value in 10 other variables (all numeric DOB variables, let's
call them X3-X12) then the identifier variable gets a value of 1 ELSE 0.

Can anyone assist with some insight on the simplest way to do this? I don't
think the way I am going about it is most efficient at all with multiple IF
commands and I also see that one can not use AND or OR unless the variable
has value of 0, 1 etc. so I am a bit stuck.

Thanks in advance for any suggestions.





--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Jon Peck
I am not sure whether you mean that X1 or X2 equals a value in at least one of X3 to X12 then the result is 1 or whether it literally has to be equality for all of X3 to X12, in which case, all the X3 to X12 values have to be the same.  So here are the two sets of code.  (A variable whose name starts with # is a scratch variable that will disappear after the code is run.)
The VECTOR command expects contigous variables in the file.  DO REPEAT could be used instead if this is not true.  The LOOP block is terminated as soon as the equality is satisified.

VECTOR X = X3 TO X12.
COMPUTE ISEQUAL = 0.
LOOP #I = 1 TO 10.
IF X1 EQ X(#I) OR X2 EQ X(#I) ISEQUAL = 1.
END LOOP IF ISEQUAL EQ 1.

EXEC.

This version check against all of X3 to X12.
COMPUTE ISEQUAL = 0.
COMPUTE #MINX = MIN(X3 TO X12).
COMPUTE #MAXX = MAX(X3 TO X12).
IF #MINX EQ #MAXX AND (X1 EQ #MINX OR X2 EQ #MINX) ISEQUAL = 1.

EXEC.



On Thu, Apr 4, 2019 at 7:59 PM J.D. Haltigan <[hidden email]> wrote:
Struggling a bit with the following challenge:

I have two variables (numeric) that are DOBs (e.g., 1997, 1996). Let's call
these X1 and X2. I need to create an identifier variable such if X1 OR X2 is
EQUAL to the value in 10 other variables (all numeric DOB variables, let's
call them X3-X12) then the identifier variable gets a value of 1 ELSE 0.

Can anyone assist with some insight on the simplest way to do this? I don't
think the way I am going about it is most efficient at all with multiple IF
commands and I also see that one can not use AND or OR unless the variable
has value of 0, 1 etc. so I am a bit stuck.

Thanks in advance for any suggestions.





--
Sent from: http://spssx-discussion.1045642.n5.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


--
Jon K Peck
[hidden email]

===================== 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: Creating a variable or function?

Rich Ulrich
In reply to this post by J.D. Haltigan
This looks like an application where any( )  makes the clearest code.

COMPUTE  ISEQUAL = any(X1, X3 to X12) OR any(X2, X3 to X12).

If X3 to X12 are not contiguous, then the commands need to list them.

--
Rich Ulrich

From: SPSSX(r) Discussion <[hidden email]> on behalf of J.D. Haltigan <[hidden email]>
Sent: Thursday, April 4, 2019 9:59 PM
To: [hidden email]
Subject: Creating a variable or function?
 
Struggling a bit with the following challenge:

I have two variables (numeric) that are DOBs (e.g., 1997, 1996). Let's call
these X1 and X2. I need to create an identifier variable such if X1 OR X2 is
EQUAL to the value in 10 other variables (all numeric DOB variables, let's
call them X3-X12) then the identifier variable gets a value of 1 ELSE 0.

Can anyone assist with some insight on the simplest way to do this? I don't
think the way I am going about it is most efficient at all with multiple IF
commands and I also see that one can not use AND or OR unless the variable
has value of 0, 1 etc. so I am a bit stuck.

Thanks in advance for any suggestions.





--
Sent from: http://spssx-discussion.1045642.n5.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
===================== 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: Creating a variable or function?

J.D. Haltigan
In reply to this post by Jon Peck
Thanks Jon, I think this is what I need. One thing, you mentioned if
variables not contiguous to use DO REPEAT. Yet, I am having difficulty
replacing VECTOR with DO REPEAT in your code. I mashed up the below to
illustrate my stab at thinking through this. FYI, I mean X1 or X2 equals a
value in at least one of X3 to X12 (not equality across them).

DO REPEAT.
*[for the x3 to x10 variables, not contiguous]*
COMPUTE ISEQUAL = 0.
LOOP #I = 1 TO 10.
IF X1 EQ X(#I) OR X2 EQ X(#I) ISEQUAL = 1.
END LOOP IF ISEQUAL EQ 1.
END REPEAT.

EXEC.



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Rich Ulrich
You need an example for the DO REPEAT, for non-contiguous?

compute  ISEQUAL= 0.
DO REPEAT  #TVAL= X3 X4 X5 X6 X7 X8 X9 X10 X11 X12.
IF  X1 eq #TVAL) or (X2 eq #TVAL)  ISEQUAL= 1.
END REPEAT.

ANY(item, list )  is handier than that.  It returns 0/1 for False/True
when first argument, "item", matches anything in the list.

"item" can be a fixed value, if you want to compare it to a list
of variables ("Do any of these variables have this value?").
"item" can be a variable, if you want to compare it to a list of values
or to a list of variables. (Mixed vals/vars probably works, but I've never
had occasion to use it.)

Using any( ) with non-contiguous variables:
compute  ISEQUAL = any (x1, x3 ,x4, x5, x6, x7, x8, x9, x10, x11, x12) OR
                            any (x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12).

--
Rich Ulrich

From: SPSSX(r) Discussion <[hidden email]> on behalf of J.D. Haltigan <[hidden email]>
Sent: Friday, April 5, 2019 1:25 AM
To: [hidden email]
Subject: Re: Creating a variable or function?
 
Thanks Jon, I think this is what I need. One thing, you mentioned if
variables not contiguous to use DO REPEAT. Yet, I am having difficulty
replacing VECTOR with DO REPEAT in your code. I mashed up the below to
illustrate my stab at thinking through this. FYI, I mean X1 or X2 equals a
value in at least one of X3 to X12 (not equality across them).

DO REPEAT.
*[for the x3 to x10 variables, not contiguous]*
COMPUTE ISEQUAL = 0.
LOOP #I = 1 TO 10.
IF X1 EQ X(#I) OR X2 EQ X(#I) ISEQUAL = 1.
END LOOP IF ISEQUAL EQ 1.
END REPEAT.

EXEC.



--
Sent from: http://spssx-discussion.1045642.n5.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
===================== 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: Creating a variable or function?

J.D. Haltigan
Thanks, Rich. Very helpful and have executed the code with success.

One thing I realized. I need to create the ISEQUAL variable such that it
only gets a 1 value if it matches 2 or more of the X3-X10 variables. As it
is now, if it matches ANY of those variables it gets a 1 value. I am not
concerned with the # of matches above 2, but 2 or more matches is my chief
interest.

Is this possible in one bolus of code or would I need to create a variable
for each X3-X10 and then use the COUNT function?



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Bruce Weaver
Administrator
In the original post, you said:

"I need to create an identifier variable such if X1 OR X2 is EQUAL to the
value in 10 other variables (all numeric DOB variables, let's call them
X3-X12) then the identifier variable gets a value of 1 ELSE 0."

In a later post, you said:

"I need to create the ISEQUAL variable such that it only gets a 1 value if
it matches 2 or more of the X3-X10 variables. As it is now, if it matches
ANY of those variables it gets a 1 value."

Here is my translation of what you've said:

  If X1 matches two or more values in X3-X12, flag = 1.
  If X2 matches two or more values in X3-X12, flag = 1.
  If X1 matches < 2 values and X2 matches < 2 values, flag = 0.

If my translation is correct, then perhaps this (untested) variation on code
posted earlier will work.


VECTOR X = X3 TO X12.
COMPUTE #count1 = 0.
COMPUTE #count2 = 0.
LOOP #I = 1 TO 10.
 IF X1 EQ X(#I) #count1 = SUM(#count1,1).
 IF X2 EQ X(#I) #count2 = SUM(#count2,1).
END LOOP IF ANY(2,#count1,#count2).
COMPUTE Flag2plus = ANY(2,#count1,#count2).
FORMATS Flag2plus(F1).
FREQUENCIES Flag2plus.

I haven't tested, so do not know for sure the scratch variables (#) will
work in this context. But I think they ought to.  

HTH.


J.D. Haltigan wrote

> Thanks, Rich. Very helpful and have executed the code with success.
>
> One thing I realized. I need to create the ISEQUAL variable such that it
> only gets a 1 value if it matches 2 or more of the X3-X10 variables. As it
> is now, if it matches ANY of those variables it gets a 1 value. I am not
> concerned with the # of matches above 2, but 2 or more matches is my chief
> interest.
>
> Is this possible in one bolus of code or would I need to create a variable
> for each X3-X10 and then use the COUNT function?
>
>
>
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (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





-----
--
Bruce Weaver
[hidden email]
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

NOTE: My Hotmail account is not monitored regularly.
To send me an e-mail, please use the address shown above.

--
Sent from: http://spssx-discussion.1045642.n5.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
--
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: Creating a variable or function?

Jon Peck
Bruce's solution does the job perfectly well, but for amusement here is a simple Python solution using the SPSSINC TRANS extension command, which can be installed from the Extensions menu.  The function atLeastTwo counts the number of occurrences of the first (X1) value and the number of occurrences of the second(X2) value  in X3 to X12 and returns 0 or 1 according to whether either these is at least 2 or not.

In the spssinc trans formula, <> stands for the variable list defined in the variables subcommand.

begin program.
def atLeastTwo(*args):
    return args[2:].count(args[0]) >=2 or args[2:].count(args[1]) >=2
end program.

spssinc trans result = isequal
/variables X1 to X12
/formula "atLeastTwo(<>)".


On Fri, Apr 5, 2019 at 8:32 AM Bruce Weaver <[hidden email]> wrote:
In the original post, you said:

"I need to create an identifier variable such if X1 OR X2 is EQUAL to the
value in 10 other variables (all numeric DOB variables, let's call them
X3-X12) then the identifier variable gets a value of 1 ELSE 0."

In a later post, you said:

"I need to create the ISEQUAL variable such that it only gets a 1 value if
it matches 2 or more of the X3-X10 variables. As it is now, if it matches
ANY of those variables it gets a 1 value."

Here is my translation of what you've said:

  If X1 matches two or more values in X3-X12, flag = 1.
  If X2 matches two or more values in X3-X12, flag = 1.
  If X1 matches < 2 values and X2 matches < 2 values, flag = 0.

If my translation is correct, then perhaps this (untested) variation on code
posted earlier will work.


VECTOR X = X3 TO X12.
COMPUTE #count1 = 0.
COMPUTE #count2 = 0.
LOOP #I = 1 TO 10.
 IF X1 EQ X(#I) #count1 = SUM(#count1,1).
 IF X2 EQ X(#I) #count2 = SUM(#count2,1).
END LOOP IF ANY(2,#count1,#count2).
COMPUTE Flag2plus = ANY(2,#count1,#count2).
FORMATS Flag2plus(F1).
FREQUENCIES Flag2plus.

I haven't tested, so do not know for sure the scratch variables (#) will
work in this context. But I think they ought to. 

HTH.


J.D. Haltigan wrote
> Thanks, Rich. Very helpful and have executed the code with success.
>
> One thing I realized. I need to create the ISEQUAL variable such that it
> only gets a 1 value if it matches 2 or more of the X3-X10 variables. As it
> is now, if it matches ANY of those variables it gets a 1 value. I am not
> concerned with the # of matches above 2, but 2 or more matches is my chief
> interest.
>
> Is this possible in one bolus of code or would I need to create a variable
> for each X3-X10 and then use the COUNT function?
>
>
>
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (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





-----
--
Bruce Weaver
[hidden email]
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

NOTE: My Hotmail account is not monitored regularly.
To send me an e-mail, please use the address shown above.

--
Sent from: http://spssx-discussion.1045642.n5.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


--
Jon K Peck
[hidden email]

===================== 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: Creating a variable or function?

J.D. Haltigan
In reply to this post by Bruce Weaver
Much appreciated, Bruce and yes you interpreted my set of messages correctly.

I attempted the addendum to the code you posted and am stuck with the fact
that since my variables are not contiguous (as noted previously) I am not
using the VECTOR command. Rather, I am using DO REPEAT. Thus, as I currently
have it, the code (with relevant variable names inserted where X was used
previously) is:

compute  RMQ_BW_INDEX= 0.
DO REPEAT  #TVAL= PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4 PREGYEAR5
PREGYEAR6
PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11 PREGYEAR12.
IF  (POND_BIRTH_YEAR eq #TVAL) or (POND_BIRTH_YEAR_PRIOR eq #TVAL)
RMQ_BW_INDEX= 1.
END REPEAT.
EXECUTE.

This returns the situation I need to use your addendum to update with the
counts, but I am not sure how to overlay the VECTOR command in your addendum
and replace it with the use of DO REPEAT which I need to use.



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

J.D. Haltigan
FWIW, I was able to translate and get the code to run but it seems to return
0 values for all cases, which I know is not correct (will double-check to be
100% certain), but in meantime figured I'd post my attempt in case any
obvious error to more senior & seasoned code writers/programmers pick up on
something.

***************.
DO REPEAT  #TVAL= PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4 PREGYEAR5
PREGYEAR6
PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11 PREGYEAR12.
COMPUTE #count1 = 0.
COMPUTE #count2 = 0.
LOOP #I = 1 TO 10.
 IF POND_BIRTH_YEAR EQ #TVAL #count1 = SUM(#count1,1).
 IF POND_BIRTH_YEAR_PRIOR EQ #TVAL #count2 = SUM(#count2,1).
END LOOP IF ANY(2,#count1,#count2).
COMPUTE Flag2plus = ANY(2,#count1,#count2).
END REPEAT.
FORMATS Flag2plus(F1).
FREQUENCIES Flag2plus.



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

PRogman
Your LOOP #I = 1 TO 10 does not do aything useful, except comparing the same
variables 10 times.
Are your POND_BIRTH_YEAR_* and PregYear* variables really of equal type
(integers)?
You also have to move the resetting of the #count* varables outside te
Repeat loop.
Suggestion below.
HTH /PR

*Example data*.
DATASET CLOSE ALL.
SET SEED 20190406.
INPUT PROGRAM.
LOOP ID = 1 TO 5.
  DO REPEAT v = PregYear1 TO PregYear12.
    COMPUTE v = TRUNC(RV.UNIFORM(1, 18))+2000.
  END REPEAT.
  END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.
DATASET NAME PregYear.

COMPUTE POND_BIRTH_YEAR       = 2012  .
COMPUTE POND_BIRTH_YEAR_PRIOR = 2011.

COMPUTE #count1 = 0.
COMPUTE #count2 = 0.
DO REPEAT  #TVAL = PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4  PREGYEAR5
PREGYEAR6
                   PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11
PREGYEAR12.
  IF (POND_BIRTH_YEAR       EQ #TVAL) #count1 = SUM(#count1, 1).
  IF (POND_BIRTH_YEAR_PRIOR EQ #TVAL) #count2 = SUM(#count2, 1).
  COMPUTE Flag2plus = ((#count1 GE 2) OR (#count2 GE 2)).
END REPEAT.
FORMATS Flag2plus(F1).

FREQUENCIES Flag2plus.








J.D. Haltigan wrote

> FWIW, I was able to translate and get the code to run but it seems to
> return
> 0 values for all cases, which I know is not correct (will double-check to
> be
> 100% certain), but in meantime figured I'd post my attempt in case any
> obvious error to more senior & seasoned code writers/programmers pick up
> on
> something.
>
> ***************.
> DO REPEAT  #TVAL= PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4 PREGYEAR5
> PREGYEAR6
> PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11 PREGYEAR12.
> COMPUTE #count1 = 0.
> COMPUTE #count2 = 0.
> LOOP #I = 1 TO 10.
>  IF POND_BIRTH_YEAR EQ #TVAL #count1 = SUM(#count1,1).
>  IF POND_BIRTH_YEAR_PRIOR EQ #TVAL #count2 = SUM(#count2,1).
> END LOOP IF ANY(2,#count1,#count2).
> COMPUTE Flag2plus = ANY(2,#count1,#count2).
> END REPEAT.
> FORMATS Flag2plus(F1).
> FREQUENCIES Flag2plus.
>
>
>
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (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





--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

J.D. Haltigan
PRogman:

This did the trick, thank you. One question. How does the code you provided
treat cases where there are system missing values on the indicators? It
appears those get a 0, but I want them (the SYSMIS instances) to receive a
sysmis in the final variable (Flag2plus).



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Art Kendall
Any time a USER assigns a missing value, the results should be a labeled
USER_MISSING value.

I suggest you go back and determine why an input value should be sysmis.
Then go back and finish the data cleaning before you do any transformations.

Also when you have a complex data transformation, it is a good habit to
complete the logic with a warning.

something like this untested untested
      ELSE
      Print 'reached a condition not provided for ' $casenum, IDvar,
somevar1, somevar2.
      outvar = -11.
END IF.

missing values outvar(...).
value labels outvar
...
-11 'weird condition'
...



-----
Art Kendall
Social Research Consultants
--
Sent from: http://spssx-discussion.1045642.n5.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
Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: Creating a variable or function?

PRogman
In reply to this post by J.D. Haltigan
Regarding evaluation of missing data please RTFM; in short: /The assignment
is executed only if the logical expression is true. If the logical
expression is false or missing, the assignment is not made./

There are several missing value functions that handle missing data, see:
Reference > Command Syntax Reference > Universals > Transformation
Expressions > Missing values.

I am not fond of inserting $sysmis into a computed variable. Using an error
code and defining it as missing value is better.

HTH/PR

*********************************.
DATASET CLOSE ALL.
SET SEED 20190406.
INPUT PROGRAM.
LOOP ID = 1 TO 5.
  DO REPEAT v = PregYear1 TO PregYear12.
    COMPUTE v = TRUNC(RV.UNIFORM(1, 18))+2000.
  END REPEAT.
  END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.
VARIABLE WIDTH PregYear1 TO PregYear12 (8).
* Missing data *.
IF (ID EQ 5) PREGYEAR12 = $SYSMIS.

COMPUTE POND_BIRTH_YEAR       = 2012  .
COMPUTE POND_BIRTH_YEAR_PRIOR = 2011.

DO REPEAT  #PY = PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4  PREGYEAR5
PREGYEAR6
                   PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11
PREGYEAR12.
  IF (POND_BIRTH_YEAR       EQ #PY) #count1 = SUM(#count1, 1).
  IF (POND_BIRTH_YEAR_PRIOR EQ #PY) #count2 = SUM(#count2, 1).
  /* Set flag if Pond_Birth_year* appears twice or more in list of PregYear*
*/.
  COMPUTE Flag2plus = ((#count1 GE 2) OR (#count2 GE 2)).
END REPEAT.

/* Missing flag if any missing indicator data */.
IF (NMISS(PREGYEAR1, PREGYEAR2, PREGYEAR3, PREGYEAR4, PREGYEAR5, PREGYEAR6,
          PREGYEAR7, PREGYEAR8, PREGYEAR9, PREGYEAR10, PREGYEAR11,
PREGYEAR12) NE 0) Flag2plus = -1.

FORMATS        Flag2plus (F1).
MISSING VALUES Flag2plus (-1).
VALUE LABELS   Flag2plus
  -1  'Indicator(s) missing'
   0  'None, or single indicator'
   1  'Multiple indicators'
.
FREQUENCIES Flag2plus.
*********************************.


J.D. Haltigan wrote

> PRogman:
>
> This did the trick, thank you. One question. How does the code you
> provided
> treat cases where there are system missing values on the indicators? It
> appears those get a 0, but I want them (the SYSMIS instances) to receive a
> sysmis in the final variable (Flag2plus).
>
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (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





--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Jon Peck
"I am not fond of inserting $sysmis into a computed variable. Using an error
code and defining it as missing value is better."

IMO, it is appropriate in general to propagate missing values, whether system or user, in the input when the result depends on this using the same type as the input.  And of course, the transformation might induce sysmis values itself.  One case where user missing might become system missing is in a transformation function like mean(x,y) where all values or x or y are user missing but the result is system missing because the mean cannot be computed - just like ln(0).

On Sun, Apr 7, 2019 at 10:05 AM PRogman <[hidden email]> wrote:
Regarding evaluation of missing data please RTFM; in short: /The assignment
is executed only if the logical expression is true. If the logical
expression is false or missing, the assignment is not made./

There are several missing value functions that handle missing data, see:
Reference > Command Syntax Reference > Universals > Transformation
Expressions > Missing values.

I am not fond of inserting $sysmis into a computed variable. Using an error
code and defining it as missing value is better.

HTH/PR

*********************************.
DATASET CLOSE ALL.
SET SEED 20190406.
INPUT PROGRAM.
LOOP ID = 1 TO 5.
  DO REPEAT v = PregYear1 TO PregYear12.
    COMPUTE v = TRUNC(RV.UNIFORM(1, 18))+2000.
  END REPEAT.
  END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.
VARIABLE WIDTH PregYear1 TO PregYear12 (8).
* Missing data *.
IF (ID EQ 5) PREGYEAR12 = $SYSMIS.

COMPUTE POND_BIRTH_YEAR       = 2012  .
COMPUTE POND_BIRTH_YEAR_PRIOR = 2011.

DO REPEAT  #PY = PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4  PREGYEAR5
PREGYEAR6
                   PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11
PREGYEAR12.
  IF (POND_BIRTH_YEAR       EQ #PY) #count1 = SUM(#count1, 1).
  IF (POND_BIRTH_YEAR_PRIOR EQ #PY) #count2 = SUM(#count2, 1).
  /* Set flag if Pond_Birth_year* appears twice or more in list of PregYear*
*/.
  COMPUTE Flag2plus = ((#count1 GE 2) OR (#count2 GE 2)).
END REPEAT.

/* Missing flag if any missing indicator data */.
IF (NMISS(PREGYEAR1, PREGYEAR2, PREGYEAR3, PREGYEAR4, PREGYEAR5, PREGYEAR6,
          PREGYEAR7, PREGYEAR8, PREGYEAR9, PREGYEAR10, PREGYEAR11,
PREGYEAR12) NE 0) Flag2plus = -1.

FORMATS        Flag2plus (F1).
MISSING VALUES Flag2plus (-1).
VALUE LABELS   Flag2plus
  -1  'Indicator(s) missing'
   0  'None, or single indicator'
   1  'Multiple indicators'
.
FREQUENCIES Flag2plus.
*********************************.


J.D. Haltigan wrote
> PRogman:
>
> This did the trick, thank you. One question. How does the code you
> provided
> treat cases where there are system missing values on the indicators? It
> appears those get a 0, but I want them (the SYSMIS instances) to receive a
> sysmis in the final variable (Flag2plus).
>
> --
> Sent from: http://spssx-discussion.1045642.n5.nabble.com/
>
> =====================
> To manage your subscription to SPSSX-L, send a message to

> LISTSERV@.UGA

>  (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





--
Sent from: http://spssx-discussion.1045642.n5.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


--
Jon K Peck
[hidden email]

===================== 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: Creating a variable or function?

Art Kendall
YMMV, but I have seen many occasions where people "shot themselves in the
foot" by not taking advantage of the distinction between values that are
missing for reasons known to the user and those values that are missing
because the syntax drafter did not communicate clearly, i.e., the system was
given instructions to do something it could not do.

statements that ASSIGN a value of sysmis have caused many problems.
compute myvar = $sysmis.


In my experience, drafting syntax is like drafting poems, drafting books,
drafting emails, drafting songs, etc.
One goes back and rethinks how one expresses one.

Finding out why sysmis values  occur and cleaning out sysmis values and
transforming them to labelled user-missing  values sometimes has to be done
many times as an analysis is drafted.

compute MyLnVar= ln(invar).
descriptives invar.
The descriptives show some sysmis.

in debugging/cleaning the snippet would become something like this but with
AUTO INDENT.

do if invar gt 0.
compute MyLnVar= ln(invar).
else if invar le 0.
print / 'oops invar was not positive ' $casenum, ID, invar.
compute MyLnVar = -999.
else if missing(invar).
print / 'oops invar was missing ' $casenum, ID, invar.
compute MyLnVar = -888.
else.
print / 'oops some unprovided for condition occurred ' $casenum, ID, invar.
compute MyLnVar = -777.
end if
missing values MyLnVar (0 thru lo).
value labels
-999 'invar was not a positive number'
-888 'invar was missing'
-777 'WEIRD a logic problem'.


mean(x,y) resulting in sysmis would have to be looked into, not just left
there.






-----
Art Kendall
Social Research Consultants
--
Sent from: http://spssx-discussion.1045642.n5.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
Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: Creating a variable or function?

J.D. Haltigan
In reply to this post by Art Kendall
The data is cleaned. I want it left as a sysmis, not a user missing at this
point. There is all kinds of difficulty with labeling as user missing etc.
if one is moving between multiple platforms such as R and Mplus and SPSS.
Depending on the platforms one is using to fully analyze their data, the
most practical approach may change.



--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

Jon Peck
Continuing the Python version, I am not clear on what sysmis conditions should generate a sysmis result.  (Also eliminated the use of TO here).

* sysmis if either of the test variables X1 or X2 is sysmis.
begin program.
def atLeastTwo(*args):
    if args[0] is None or args[1] is None:
         return None
    return args[2:].count(args[0]) >=2 or args[2:].count(args[1]) >=2
end program.

* sysmis if any variable is sysmis.
begin program.
def atLeastTwo(*args):
    if None in args:
         return None
    return args[2:].count(args[0]) >=2 or args[2:].count(args[1]) >=2
end program.

spssinc trans result = isequal
/formula "atLeastTwo(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12)".


On Sun, Apr 7, 2019 at 2:59 PM J.D. Haltigan <[hidden email]> wrote:
The data is cleaned. I want it left as a sysmis, not a user missing at this
point. There is all kinds of difficulty with labeling as user missing etc.
if one is moving between multiple platforms such as R and Mplus and SPSS.
Depending on the platforms one is using to fully analyze their data, the
most practical approach may change.



--
Sent from: http://spssx-discussion.1045642.n5.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


--
Jon K Peck
[hidden email]

===================== 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: Creating a variable or function?

J.D. Haltigan
In reply to this post by PRogman
Thanks PRogman again.

What I need, and which I hope is not exceptionally difficult to master is
for the code you provided previously to handle any situation in which ALL of
the PREGYEAR variables have a sysmis instance to generate the resultant
output variable Flag2plus to be SYSMIS. This is because if any of the
PREGYEAR variables have a valid entry, then data is present and it can be
either 0 or 1 depending on the other criteria specified as to additional
potential PREGYEAR instances.

Now I could recode the data so that all SYSMIS are flagged as some unique
value and defined as such in the editor, but I don't particularly want to
take this approach. That said, whatever is most efficient will do.





--
Sent from: http://spssx-discussion.1045642.n5.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: Creating a variable or function?

J.D. Haltigan
Check that:

Made one tweak reflected below due to a miscommunication on my part (missing
ALL rather than ANY indicator data) and am now getting what I need. Thanks
again, PRogman.

COMPUTE #count1 = 0.
COMPUTE #count2 = 0.

DO REPEAT  #TVAL= PREGYEAR1 PREGYEAR2 PREGYEAR3 PREGYEAR4 PREGYEAR5
PREGYEAR6
PREGYEAR7 PREGYEAR8 PREGYEAR9 PREGYEAR10 PREGYEAR11 PREGYEAR12.

 IF POND_BIRTH_YEAR EQ #TVAL #count1 = SUM(#count1,1).
 IF POND_BIRTH_YEAR_PRIOR EQ #TVAL #count2 = SUM(#count2,1).

COMPUTE AMBIGUOUS_POND_RMQ = ((#count1 GE 2) OR (#count2 GE 2)).
END REPEAT.

/* Missing flag if all missing indicator data */.
IF (NMISS(PREGYEAR1, PREGYEAR2, PREGYEAR3, PREGYEAR4, PREGYEAR5, PREGYEAR6,
          PREGYEAR7, PREGYEAR8, PREGYEAR9, PREGYEAR10, PREGYEAR11,
PREGYEAR12) *GE 12*) AMBIGUOUS_POND_RMQ = -1.

FORMATS AMBIGUOUS_POND_RMQ(F1).
MISSING VALUES AMBIGUOUS_POND_RMQ (-1).
VALUE LABELS AMBIGUOUS_POND_RMQ
"-1" 'All PREGYEARS missing'
"0" 'Matching Unique RMQ Preg Year'
"1" 'Multiple Possible RMQ Preg Years'.



--
Sent from: http://spssx-discussion.1045642.n5.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
12