Loop to repeat simple commands with variables whose names are very similar

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

Loop to repeat simple commands with variables whose names are very similar

krudolph
I have several variables that have very similar names that I need to add
together.  I have used For Loops in other programming languages but I can't
figure out how to do it in SPSS.

eg.

COMPUTE LH_LE_NORM_I1_NULLmean_plusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 +
    LH_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

COMPUTE LH_LE_NORM_I1_NULLmean_minusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 -
    LH_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

The variables are all named exactly the same way except the LH at the
beginning of the variable name changes to MG RF SOL TA and VL  

eg.

COMPUTE MG_LE_NORM_I1_NULLmean_plusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 +
    MG_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

COMPUTE MG_LE_NORM_I1_NULLmean_minusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 -
    MG_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

I would like to make a variable that contains a list of the initials and
then replace the "LH" in the commands with each item in the list.

I hope I've explained this well enough.  Any suggestions?

Thank you in advance.



--
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: Loop to repeat simple commands with variables whose names are very similar

Maguin, Eugene
There's a very nice function (documented (Universals -> Numeric functions) in the syntax reference) named Mean.x and it works like this:
compute zz=mean.1(q1,q2,q3).
OR
compute zz=mean.1(q1 to q31).

The 'x' parameter controls how many of the variables must have valid values for the result to be computed. Mean.5 requires that at least 5 of the named variables have valid values

Gene Maguin
________________________________________
From: SPSSX(r) Discussion <[hidden email]> on behalf of krudolph <[hidden email]>
Sent: Monday, September 9, 2019 1:38 PM
To: [hidden email]
Subject: Loop to repeat simple commands with variables whose names are very similar

I have several variables that have very similar names that I need to add
together.  I have used For Loops in other programming languages but I can't
figure out how to do it in SPSS.

eg.

COMPUTE LH_LE_NORM_I1_NULLmean_plusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 +
    LH_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

COMPUTE LH_LE_NORM_I1_NULLmean_minusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 -
    LH_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

The variables are all named exactly the same way except the LH at the
beginning of the variable name changes to MG RF SOL TA and VL

eg.

COMPUTE MG_LE_NORM_I1_NULLmean_plusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 +
    MG_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

COMPUTE MG_LE_NORM_I1_NULLmean_minusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 -
    MG_LE_NORM_I1_avg_norm_I1t_sd.
EXECUTE.

I would like to make a variable that contains a list of the initials and
then replace the "LH" in the commands with each item in the list.

I hope I've explained this well enough.  Any suggestions?

Thank you in advance.



--
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: Loop to repeat simple commands with variables whose names are very similar

Bruce Weaver
Administrator
In reply to this post by krudolph
I understood the question a bit differently that Gene did.  If I follow, the
following DO-REPEAT structure will give the desired result:

DO REPEAT
 Result = LH_LE_NORM_I1_NULLmean_plusSD MG_LE_NORM_I1_NULLmean_plusSD
             RF_LE_NORM_I1_NULLmean_plusSD  SOL_LE_NORM_I1_NULLmean_plusSD
            TA_LE_NORM_I1_NULLmean_plusSD VL_LE_NORM_I1_NULLmean_plusSD /
 M = LH_LE_NORM_I1_avg_norm_I1t_mean_1 MG_LE_NORM_I1_avg_norm_I1t_mean_1
        RF_LE_NORM_I1_avg_norm_I1t_mean_1 SOL_LE_NORM_I1_avg_norm_I1t_mean_1
       TA_LE_NORM_I1_avg_norm_I1t_mean_1 VL_LE_NORM_I1_avg_norm_I1t_mean_1 /
 S = LH_LE_NORM_I1_avg_norm_I1t_sd MG_LE_NORM_I1_avg_norm_I1t_sd
       RF_LE_NORM_I1_avg_norm_I1t_sd  SOL_LE_NORM_I1_avg_norm_I1t_sd
       TA_LE_NORM_I1_avg_norm_I1t_sd VL_LE_NORM_I1_avg_norm_I1t_sd.
COMPUTE Result = M+S.
END REPEAT.
EXECUTE.

But given the length of those variable names, that code is ugly and probably
hard to maintain.  Here's a macro that does the same thing:

* Define the macro.
DEFINE !myloop (list = !CMDEND)

!DO !prefix !IN (!list)
!LET !result = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_plusSD")
!LET !mean = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_mean_1")
!LET !sd = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_sd")

COMPUTE !result = !mean + !sd.

!DOEND  
!ENDDEFINE.
* End of macro definition.

* Now call the macro.
* When you have verified that it works, you might
* wish to remove or comment out the two SET commands.

SET MPRINT ON.
!myloop list = LH MG RF SOL TA VL.
EXECUTE.
SET MPRINT OFF.


When I ran this code, a lot of errors were generated because I had no
dataset with the needed variable names.  But I could see that the code
generated the following COMPUTE commands:


COMPUTE LH_LE_NORM_I1_NULLmean_plusSD = LH_LE_NORM_I1_avg_norm_I1t_mean_1 +
LH_LE_NORM_I1_avg_norm_I1t_sd.
 
COMPUTE MG_LE_NORM_I1_NULLmean_plusSD = MG_LE_NORM_I1_avg_norm_I1t_mean_1 +
MG_LE_NORM_I1_avg_norm_I1t_sd.
 
COMPUTE RF_LE_NORM_I1_NULLmean_plusSD = RF_LE_NORM_I1_avg_norm_I1t_mean_1 +
RF_LE_NORM_I1_avg_norm_I1t_sd.
 
COMPUTE SOL_LE_NORM_I1_NULLmean_plusSD = SOL_LE_NORM_I1_avg_norm_I1t_mean_1
+ SOL_LE_NORM_I1_avg_norm_I1t_sd.
 
COMPUTE TA_LE_NORM_I1_NULLmean_plusSD = TA_LE_NORM_I1_avg_norm_I1t_mean_1 +
TA_LE_NORM_I1_avg_norm_I1t_sd.
 
COMPUTE VL_LE_NORM_I1_NULLmean_plusSD = VL_LE_NORM_I1_avg_norm_I1t_mean_1 +
VL_LE_NORM_I1_avg_norm_I1t_sd.
 

I think this is what the OP was looking for.  If not, please clarify.

PS- I borrowed a macro that Mario posted in the "Macro for GLM thread
(http://spssx-discussion.1045642.n5.nabble.com/Macro-for-GLM-td5738269.html)
and tweaked it a bit.  




krudolph wrote

> I have several variables that have very similar names that I need to add
> together.  I have used For Loops in other programming languages but I
> can't
> figure out how to do it in SPSS.
>
> eg.
>
> COMPUTE LH_LE_NORM_I1_NULLmean_plusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 +
>     LH_LE_NORM_I1_avg_norm_I1t_sd.
> EXECUTE.
>
> COMPUTE LH_LE_NORM_I1_NULLmean_minusSD=LH_LE_NORM_I1_avg_norm_I1t_mean_1 -
>     LH_LE_NORM_I1_avg_norm_I1t_sd.
> EXECUTE.
>
> The variables are all named exactly the same way except the LH at the
> beginning of the variable name changes to MG RF SOL TA and VL  
>
> eg.
>
> COMPUTE MG_LE_NORM_I1_NULLmean_plusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 +
>     MG_LE_NORM_I1_avg_norm_I1t_sd.
> EXECUTE.
>
> COMPUTE MG_LE_NORM_I1_NULLmean_minusSD=MG_LE_NORM_I1_avg_norm_I1t_mean_1 -
>     MG_LE_NORM_I1_avg_norm_I1t_sd.
> EXECUTE.
>
> I would like to make a variable that contains a list of the initials and
> then replace the "LH" in the commands with each item in the list.
>
> I hope I've explained this well enough.  Any suggestions?
>
> Thank you in advance.
>
>
>
> --
> 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."

NOTE: My Hotmail account is not monitored regularly.
To send me an e-mail, please use the address shown above.
Reply | Threaded
Open this post in threaded view
|

Re: Loop to repeat simple commands with variables whose names are very similar

Tim Graettinger
In reply to this post by krudolph
Hi,

For me, the SPSS Python extension has been really useful as the solution to the kind of 'for loop' problems you want to solve in your post - and for string substitutions of the sort you want to do as well.  If you're willing to learn some Python (and install the Python extension, if you haven't already), it can be really powerful.  If not, I don't want to waste your time with a long response.  A Python version of your SPSS syntax would look something like this:

BEGIN PROGRAM PYTHON.

prefixList = [LH, MG, RF, SOL, TA, VL]

for prefix in prefixList:
     spss.Submit('''COMPUTE %s_LE_NORM...=%s_LE... +%s_LE...).''' % (prefix, prefix, prefix))
     spss.Submit('''COMPUTE %s_LE_NORM...=%s_LE... +%s_LE...).''' % (prefix, prefix, prefix))

spss.Submit('''EXECUTE.''')

END PROGRAM PYTHON.

Where there are ...'s above, you would have the missing bits of your COMPUTE statements.  Just didn't want to write them all out.  Everywhere there is a %s in the spss.Submit statement, it gets replaced by one of the items in the tuple at the end of the line, in this case, one of the prefixes.  Hope this makes some sense.  If you want more details, shoot me an email.  Best,
-Tim

=====================
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: Loop to repeat simple commands with variables whose names are very similar

PRogman
In reply to this post by Bruce Weaver
I thought the same, but there were two posts: mean+sd and mean-sd.
so adding
  !LET !resultMSD = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_minusSD")
and further down
  COMPUTE !resultMSD = !mean -!sd.
which implies that I would have named the the other "!resultPSD"

:-), PR


Bruce Weaver wrote

> ...
> But given the length of those variable names, that code is ugly and
> probably
> hard to maintain.  Here's a macro that does the same thing:
>
> * Define the macro.
> DEFINE !myloop (list = !CMDEND)
>
> !DO !prefix !IN (!list)
> !LET !result = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_plusSD")
> !LET !mean = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_mean_1")
> !LET !sd = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_sd")
>
> COMPUTE !result = !mean + !sd.
>
> !DOEND  
> !ENDDEFINE.
> * End of macro definition.
>
> * Now call the macro.
> * When you have verified that it works, you might
> * wish to remove or comment out the two SET commands.
>
> SET MPRINT ON.
> !myloop list = LH MG RF SOL TA VL.
> EXECUTE.
> SET MPRINT OFF.
> ...





--
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: Loop to repeat simple commands with variables whose names are very similar

Bruce Weaver
Administrator
Good catch PRogman!  And apologies to the OP for misreading it.  

For the record, here is the revised macro (untested--no SPSS on this
computer).

* Define the macro.
DEFINE !myloop (list = !CMDEND)

!DO !prefix !IN (!list)
!LET !resultPSD = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_plusSD")
!LET !resultMSD = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_minusSD")
!LET !mean = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_mean_1")
!LET !sd = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_sd")

COMPUTE !resultPSD = !mean + !sd.
COMPUTE !resultMSD = !mean - !sd.

!DOEND  
!ENDDEFINE.
* End of macro definition.



PRogman wrote

> I thought the same, but there were two posts: mean+sd and mean-sd.
> so adding
>   !LET !resultMSD = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_minusSD")
> and further down
>   COMPUTE !resultMSD = !mean -!sd.
> which implies that I would have named the the other "!resultPSD"
>
> :-), PR
>
>
> Bruce Weaver wrote
>> ...
>> But given the length of those variable names, that code is ugly and
>> probably
>> hard to maintain.  Here's a macro that does the same thing:
>>
>> * Define the macro.
>> DEFINE !myloop (list = !CMDEND)
>>
>> !DO !prefix !IN (!list)
>> !LET !result = !CONCAT(!prefix,"_LE_NORM_I1_NULLmean_plusSD")
>> !LET !mean = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_mean_1")
>> !LET !sd = !CONCAT(!prefix,"_LE_NORM_I1_avg_norm_I1t_sd")
>>
>> COMPUTE !result = !mean + !sd.
>>
>> !DOEND  
>> !ENDDEFINE.
>> * End of macro definition.
>>
>> * Now call the macro.
>> * When you have verified that it works, you might
>> * wish to remove or comment out the two SET commands.
>>
>> SET MPRINT ON.
>> !myloop list = LH MG RF SOL TA VL.
>> EXECUTE.
>> SET MPRINT OFF.
>> ...
>
>
>
>
>
> --
> 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."

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