macro help

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

macro help

Dominic Lusinchi
Dear colleagues,



First of all, this is a long email and I apologize for that.



Second I am a macro rookie, so what you will see, if you read on, is
probably not very elegant.



Any HELP much appreciated.



Here is what I want to do:



From a set of 10 scores (or n scores, more generally) I want to



1) select 5 (or m, more generally, where m < n),

2) compute the mean (or any other statistic for that matter) of those 5
scores then

3) do the same for the 5 remaining scores (n-m scores),

4) then compute the difference (or some other operation) and

5) put the result in a separate file,

6) finally repeat steps 1 through 5 x number of times.



I have written the conventional syntax for the steps above, although the
steps in the syntax are not in the order listed above.



I have appended the syntax (perhaps it could use some improvement too!) at
the bottom of the message after the macro.



Here is the test data set (entitled testdata1.sav) for the macro.



DATA LIST FREE/ id score .

VAR LAB  id 'ID'  /score 'Score'.

VAR WID id score (7).

BEGIN DATA

1 90

2 81

3 82

4 79

5 98

6 91

7 95

8 93

9 85

10 92

END DATA.



Here is the macro.



DEFINE !mymacro (myfile = !TOKENS (1)

            /myvar = !TOKENS (1)

            /mym = !TOKENS (1)

            /myn = !TOKENS (1)

            /myobs = !TOKENS (1))



!DO !i = 1 !TO !myobs.



GET

  FILE=!myfile.



SAMPLE !mym FROM !myn.

RENAME VARIABLES !myvar=score1.

SAVE OUTFILE='C:\temp\testdata2.sav' .

GET

  FILE=!myfile.

MATCH FILES /FILE=*

 /FILE='C:\temp\testdata2.sav'

 /BY id.



IF SYSMIS(score1) score2=!myvar .



DELETE VAR  id !myvar score1.

SELECT IF (score2>0).

COMPUTE id=$CASENUM.

SAVE OUTFILE='C:\temp\testdata3.sav' .

GET

  FILE='C:\temp\testdata2.sav'.

DELETE VAR  id .

COMPUTE nuid=$CASENUM.

RENAME VARIABLE nuid=id.

MATCH FILES /FILE=*

 /FILE='C:\temp\testdata3.sav'

 /BY id.

SAVE OUTFILE='C:\temp\testdata4.sav' .

DELETE VARIABLES id.

FLIP

  VARIABLES=score1 score2  .

SET MESSAGES=NONE .

DELETE VARIABLES CASE_LBL .

COMPUTE x_bar=MEAN(var001 TO var005).

SAVE OUTFILE='C:\temp\testdata5.sav' .

DELETE VARIABLES  var001 TO var005 .

FLIP

  VARIABLES=x_bar  .

SET MESSAGES=NONE .

DELETE VARIABLES CASE_LBL .

RENAME VARIABLES var001 = group1  var002 = group2.



!DOEND.



COMPUTE grpdiff = group1 - group2 .

VAR LAB  group1 'Group 1'  /group2 'Group 2'  /grpdiff 'Mean Difference' .

VAR WID group1 group2 grpdiff  (7).

FORMATS group1 group2 grpdiff (F8.2) .

SAVE OUTFILE='C:\My Documents\diffdata.sav' .



!ENDDEFINE.



!mymacro myfile='C:\My Documents\testdata1.sav'

   myvar=score mym=5 myn=10 myobs=3.



When I run the macro, which fails miserably, it does not do any looping. I
ask for 3 loops in the macro call (myobs=3), but the macro just runs the
syntax as if it were not in the macro. So it gives me one result and stops.
I get error messages but they do not relate to the macro but to the syntax
in the body of the macro. The errors are due to the fact that I use the
DELETE command while transformations are pending. I also get an output for
the FLIP command because I do not include the "SET MESSAGES=NONE" in the
syntax that I put in the macro.



Here is the conventional syntax that yields the result I am looking for -
but only once!



GET

  FILE='C:\My Documents\testdata1.sav'.

SAMPLE 5 FROM 10.

RENAME VARIABLES score=score1.

SAVE OUTFILE='C:\temp\testdata2.sav' .

GET

  FILE='C:\My Documents\testdata1.sav'.

MATCH FILES /FILE=*

 /FILE='C:\temp\testdata2.sav'

 /BY id.

EXECUTE.

IF SYSMIS(score1) score2=score.

EXE.

DELETE VAR  id score score1.

SELECT IF (score2>0).

COMPUTE id=$CASENUM.

SAVE OUTFILE='C:\temp\testdata3.sav' .

GET

  FILE='C:\temp\testdata2.sav'.

DELETE VAR  id .

COMPUTE nuid=$CASENUM.

RENAME VARIABLE nuid=id.

MATCH FILES /FILE=*

 /FILE='C:\temp\testdata3.sav'

 /BY id.

SAVE OUTFILE='C:\temp\testdata4.sav' .

DELETE VARIABLES id.

FLIP

  VARIABLES=score1 score2  .

SET RESULTS =NONE .

DELETE VARIABLES CASE_LBL .

COMPUTE x_bar=MEAN(var001 TO var005).

SAVE OUTFILE='C:\temp\testdata5.sav' .

DELETE VARIABLES  var001 TO var005 .

FLIP

  VARIABLES=x_bar  .

SET RESULTS=NONE .

DELETE VARIABLES CASE_LBL .

RENAME VARIABLES var001 = group1  var002 = group2.

COMPUTE grpdiff = group1 - group2 .

VAR LAB  group1 'Group 1'  /group2 'Group 2'  /grpdiff 'Mean Difference' .

VAR WID group1 group2 grpdiff  (7).

FORMATS group1 group2 grpdiff (F8.2) .

SAVE OUTFILE='C:\My Documents\diffdata.sav' .



THANK YOU in advance for any assistance you can provide.



Best regards,

Dominic



**********************************************

Dominic Lusinchi

Statistical Consultant & Partner



Far West Research

Statistical Consulting



San Francisco, California



Telephone: 415-664-3032

Fax: 415-664-4459

Emai: [hidden email]

Web: www.farwestresearch.com

**********************************************
Reply | Threaded
Open this post in threaded view
|

Re: macro help

Richard Ristow
At 12:15 PM 10/27/2006, Dominic Lusinchi wrote:

> From a set of 10 scores (or n scores, more generally) I want to
>1) select 5 (or m, more generally, where m < n),
>2) compute the mean (or any other statistic for that matter) of those
>5
>scores then
>3) do the same for the 5 remaining scores (n-m scores),
>4) then compute the difference (or some other operation) and
>5) put the result in a separate file,
>6) finally repeat steps 1 through 5 x number of times.

As to that - let's make that another post.

>When I run the macro, which fails miserably, it does not do any
>looping. I ask for 3 loops in the macro call (myobs=3), but the macro
>just runs the syntax as if it were not in the macro. So it gives me
>one result and stops.

According to my tests, it does loop; it just doesn't save its output.
I'm not going to post all the output, which is lengthy. I *think* this
is your problem. It's from my revised version; I use different file
names, and have some extra statements in to trace the run:

.     DELETE VARIABLES CASE_LBL .
.     RENAME VARIABLES var001 = group1
                        var002 = group2.
.     ECHO  !QUOTE(!CONCAT('End   of loop pass ',!i)).

!DOEND.


.  COMPUTE grpdiff = group1 - group2 .
.  VAR LAB  group1 'Group 1'  /group2 'Group 2'
            /grpdiff 'Mean Difference' .
.  VAR WID group1 group2 grpdiff  (7).
.  FORMATS group1 group2 grpdiff (F8.2) .
.  SAVE OUTFILE=Output .
.  /**/ LIST.
.  ECHO  'End of macro. Output listed above'.
.  ECHO  !QUOTE(!CONCAT('     Call  : ',!1)).

!ENDDEFINE.

Above, you're generating output file that I name "Output" and you call
'C:\My Documents\diffdata.sav'. But you're only writing it ONCE, after
the loop has completed. It has the results of the third loop pass, but
only that one.

Here's the code I ran:

DEFINE !mymacro (myfile = !TOKENS (1)
             /myvar = !TOKENS (1)
             /mym   = !TOKENS (1)
             /myn   = !TOKENS (1)
             /myobs = !TOKENS (1))

    !DO !i = 1 !TO !myobs.
.     ECHO  !QUOTE(!CONCAT('Start of loop pass ',!i)).
.     GET FILE=!myfile.

.     SAMPLE !mym FROM !myn.
.     RENAME VARIABLES !myvar=score1.
.     SAVE OUTFILE=Temp2 .
.     GET FILE=!myfile.
.     MATCH FILES
          /FILE=*
          /FILE=Temp2
          /BY id.

.     IF SYSMIS(score1) score2=!myvar .
.
.     DELETE VAR  id !myvar score1.
.     SELECT IF (score2>0).
.     COMPUTE id=$CASENUM.
.     SAVE OUTFILE=Temp3 .
.     GET FILE=Temp2.
.     DELETE VAR  id .
.     COMPUTE nuid=$CASENUM.
.     RENAME VARIABLE nuid=id.
.     MATCH FILES
          /FILE=*
          /FILE=Temp3
          /BY id.
.     SAVE OUTFILE=Temp4 .
.     DELETE VARIABLES id.
.     FLIP VARIABLES=score1 score2  .
.     SET MESSAGES=NONE .
.     DELETE VARIABLES CASE_LBL .
.     COMPUTE x_bar=MEAN(var001 TO var005).
.     SAVE OUTFILE=Temp5 .
.     DELETE VARIABLES  var001 TO var005 .
.     FLIP VARIABLES=x_bar  .
.     SET MESSAGES=NONE .
.     DELETE VARIABLES CASE_LBL .
.     RENAME VARIABLES var001 = group1
                        var002 = group2.
.     ECHO  !QUOTE(!CONCAT('End   of loop pass ',!i)).

!DOEND.


.  COMPUTE grpdiff = group1 - group2 .
.  VAR LAB  group1 'Group 1'  /group2 'Group 2'
            /grpdiff 'Mean Difference' .
.  VAR WID group1 group2 grpdiff  (7).
.  FORMATS group1 group2 grpdiff (F8.2) .
.  SAVE OUTFILE=Output .
.  /**/ LIST.
.  ECHO  'End of macro. Output listed above'.

!ENDDEFINE.

PRESERVE.
*SET MPRINT ON.
!mymacro myfile=TestData
    myvar=score mym=5 myn=10 myobs=3.
RESTORE.
.........................................
And here's the output. I warned you it was lengthy; but you'll see that
all three loop passes occur.


PRESERVE.
*SET MPRINT ON.
!mymacro myfile=TestData
    myvar=score mym=5 myn=10 myobs=3.
Start of loop pass 1


Delete Variables
|--------------------------|---------------|
|Output Created            |29-OCT-2006    |
|                          |21:53:40       |
|--------------------------|---------------|
Warnings
|---------------|
|Variables can  |
|not be deleted |
|while          |
|transformations|
|are pending.   |
|---------------|
|This command is|
|not executed.  |
|---------------|

FLIP performed on 5 cases and 3 variables, creating 2 cases
and 6 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.

New variable names:
CASE_LBL var001 var002 var003 var004 var005


FLIP performed on 2 cases and 1 variables, creating 1 cases
and 3 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.

New variable names:

CASE_LBL var001 var002

End   of loop pass 1
Start of loop pass 2


Delete Variables
|--------------------------|---------------|
|Output Created            |29-OCT-2006    |
|                          |21:53:42       |
|--------------------------|---------------|
Warnings
|---------------|
|Variables can  |
|not be deleted |
|while          |
|transformations|
|are pending.   |
|---------------|
|This command is|
|not executed.  |
|---------------|

FLIP performed on 5 cases and 3 variables, creating 2 cases
and 6 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.

New variable names:

CASE_LBL var001 var002 var003 var004 var005

FLIP performed on 2 cases and 1 variables, creating 1 cases
and 3 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.

New variable names:

CASE_LBL var001 var002


End   of loop pass 2
Start of loop pass 3


Delete Variables
|--------------------------|---------------|
|Output Created            |29-OCT-2006    |
|                          |21:53:45       |
|--------------------------|---------------|
Warnings
|---------------|
|Variables can  |
|not be deleted |
|while          |
|transformations|
|are pending.   |
|---------------|

FLIP performed on 5 cases and 3 variables, creating 2 cases
and 6 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.

New variable names:

CASE_LBL var001 var002 var003 var004 var005

FLIP performed on 2 cases and 1 variables, creating 1 cases
and 3 variables.  The working file has been replaced.

A new variable has been created called CASE_LBL.  Its
contents are the old variable names.


New variable names:
CASE_LBL var001 var002


End   of loop pass 3


List
|-----------------------------|---------------|
|Output Created               |29-OCT-2006    |
|                             |21:53:47       |
|-----------------------------|---------------|
   group1   group2  grpdiff

    86.20    91.00    -4.80


Number of cases read:  1    Number of cases listed:  1

End of macro. Output listed above
RESTORE.
Reply | Threaded
Open this post in threaded view
|

Re: macro help

Richard Ristow
In reply to this post by Dominic Lusinchi
A second point.

At 12:15 PM 10/27/2006, Dominic Lusinchi wrote:

>I have appended the syntax (perhaps it could use some improvement
>too!) at
>the bottom of the message after the macro.

Yes; you've made it much harder than it needs to be.

You average values over several cases by using FLIP and then the MEAN()
function. That is extremely clumsy. Use AGGREGATE instead.

That'll probably mean you can do without most of your DELETE VARIABLES
statements.

Finally, rather than using SAMPLE and then MATCH FILES to identify the
cases not selected, you can divide the cases into the two groups
yourself, and not have to save and reload. There are several ways to
assign cases randomly to groups; in another posting, you use the
random-sort method.

Good luck,
Richard
Reply | Threaded
Open this post in threaded view
|

Re: macro help

Dominic Lusinchi
Thank you, Richard, for getting involved with this and for your valuable
feedback.

Yes, I finally realized that the macro was looping but not saving the
results. I was able to fix all of the issues. However, I will take a close
look at your suggestions in order to streamline the code and make it more
efficient.

Best regards,
Dominic

Dominic Lusinchi
Statistician
Far West Research
Statistical Consulting
San Francisco, California
415-664-3032
www.farwestresearch.com

-----Original Message-----
From: SPSSX(r) Discussion [mailto:[hidden email]] On Behalf Of
Richard Ristow
Sent: Sunday, October 29, 2006 7:17 PM
To: [hidden email]
Subject: Re: macro help

A second point.

At 12:15 PM 10/27/2006, Dominic Lusinchi wrote:

>I have appended the syntax (perhaps it could use some improvement
>too!) at
>the bottom of the message after the macro.

Yes; you've made it much harder than it needs to be.

You average values over several cases by using FLIP and then the MEAN()
function. That is extremely clumsy. Use AGGREGATE instead.

That'll probably mean you can do without most of your DELETE VARIABLES
statements.

Finally, rather than using SAMPLE and then MATCH FILES to identify the
cases not selected, you can divide the cases into the two groups
yourself, and not have to save and reload. There are several ways to
assign cases randomly to groups; in another posting, you use the
random-sort method.

Good luck,
Richard