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 ********************************************** |
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. |
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 |
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 |
Free forum by Nabble | Edit this page |