I posted something similar but slightly different a couple of weeks ago.
I have monthly data and I need to create new variables that are the mean of trailing three months. For example with data like this data list list / start V2011_1 to V2011_12 (13f5.0). begin data 1 1 2 3 4 5 6 7 8 9 10 11 12 2 1 2 3 4 5 6 7 8 9 10 11 12 3 12 11 10 9 8 7 6 5 4 3 2 1 4 12 11 10 9 8 7 6 5 4 3 2 1 end data. I would need to get Average2011_3 = mean(V2011_1 to V2011_3). Average2011_4 = mean(V2011_2 to V2011_4). Average2011_5 = mean(V2011_3 to V2011_5). etc. I need to do this for several years and for several types of variables so I think a macro would be helpful. I thought know my way around macros with !do commands but they don't work, I guess I need loop commands and they are definitely not my strongest side - any advice is greatly appreciated. Matt ===================== 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 |
Administrator
|
Try this:
numeric Average2011_3 to Average2011_12 (f5.2). vector v = V2011_1 to V2011_12 / a = Average2011_3 to Average2011_12. loop # = 1 to 10 . - compute a(#) = 0. - loop ## = # to #+2 . - compute a(#) = a(#) + v(##). - end loop. - compute a(#) = a(#)/3. end loop. execute.
--
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/). |
In reply to this post by Eric Black
Thanks so much Bruce
I found a slightly different way - not sure if I make things more complicated that way: vector TTMvector = Average2011_3 to Average2011_12. vector M1Vector = V2011_1 to V2011_10. vector M2Vector = V2011_2 to V2011_11. vector M3Vector = V2011_3 to V2011_12. loop #item = 1 to 9. + compute TTMvector(#item) = sum(M1Vector(#item), M2Vector(#item), M3Vector(#item) ). end loop. exe. ===================== 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 |
Administrator
|
Here's a simplification of what I posted, using the MEAN function in place of the nested loop.
numeric Average2011_3 to Average2011_12 (f5.1). vector v = V2011_1 to V2011_12 / a = Average2011_3 to Average2011_12. loop # = 1 to 10 . - compute a(#) = MEAN(v(#), v(#+1), v(#+2)). end loop. execute.
--
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/). |
Administrator
|
In reply to this post by Eric Black
Slightly out of character for me ;-)
--- data list free / x1 TO x10. BEGIN DATA 1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 END DATA. VARSTOCASES MAKE Xvar FROM ALL/ ID ID. SPLIT FILE BY ID. CREATE AVG3=MA(XVar,3). CASESTOVARS ID=ID .
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?" |
Administrator
|
Yes, just slightly! :-O
BTW, thanks for the clarification on XSAVE in that other thread.
--
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/). |
In reply to this post by Eric Black
Thanks Bruce
This does work - I get the right results but I get an error message Below is the adjusted script I use for a 12 months trailing period. I assume I can use v(#-1) and simply go backwards: vector v = S_201007 to S_201112 / a = S_T12M_201007 to S_T12M_201112 . loop # = 1 to 18 . - compute a(#) = MEAN(v(#), v(#-1), v(#-2), v(#-3), v(#-4), v(#-5), v(#-6), v(#-7), v(#-8), v(#-9), v(#-10), v(#-11) ). end loop. execute. The error message says >Warning # 513 >The subscript in a vector reference is missing or otherwise invalid. The >subscript must be a positive integer and must not be greater than the length >of the vector. The result has been set to the system-missing value. ===================== 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 |
Administrator
|
Hint: v(#-11) ???
#-11 as a subscript is negative (UNDEFINED/INVALID) until you get to #=12!!! *AND* if the variables used for the VECTOR a ie; S_T12M_201007 to S_T12M_201112 are declared as NUMERIC S_T12M_201007 to S_T12M_201112 (Fw.d) the whole thing is a mess. ie: You are implicitly declaring 201112-201007 (180,895) variables. OTOH: NUMERIC S_T12M_201007 to S_T12M_201012 S_T12M_201107 to S_T12M_201112 (Fw.d) will only define 10 new variables. There is something fundamentally askew/bramaged in your approach. Rethink your naming strategy, draw a flow chart and try again. ---
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?" |
In reply to this post by Eric Black
David
The thing is not a "mess." I deal with monthly data, so I name them yyyymm. This is simply easier than having Month3898 and nobody knows what month that means. It might very well be that the approach that Bruce suggested doesn't work with such a naming convention and I am happy to use my approach which is longer but in the long run easier than renaming variables back and forth to fit a shorter macro. Not sure why my question caused you to call the approach to be "fundamentally [..] bramaged" but I can assure you that your approach is definitely not appropriate. I appreciate your willingness to help out and maybe the majority of participants on this group find your method of teaching helpful, but in my opinion a willingness to help doesn't mean that you are free to ignore the basics of netiquette. Just my 2 cents On Fri, 17 Feb 2012 10:21:47 -0800, David Marso <[hidden email]> wrote: >Hint: v(#-11) ??? >#-11 as a subscript is negative (UNDEFINED/INVALID) until you get to #=12!!! >*AND* if the variables used for the VECTOR a ie; S_T12M_201007 to >S_T12M_201112 >are declared as NUMERIC S_T12M_201007 to S_T12M_201112 (Fw.d) the whole >thing is a mess. >ie: You are implicitly declaring 201112-201007 (180,895) variables. >OTOH: NUMERIC S_T12M_201007 to S_T12M_201012 S_T12M_201107 to S_T12M_201112 >(Fw.d) >will only define 10 new variables. There is something fundamentally >askew/bramaged in your approach. >Rethink your naming strategy, draw a flow chart and try again. >--- > >matti wrote >> >> Thanks Bruce >> >> This does work - I get the right results but I get an error message >> >> Below is the adjusted script I use for a 12 months trailing period. I >> assume I can use v(#-1) and simply go backwards: >> >> vector v = S_201007 to S_201112 / a = S_T12M_201007 to S_T12M_201112 . >> loop # = 1 to 18 . >> - compute a(#) = MEAN(v(#), v(#-1), v(#-2), v(#-3), v(#-4), v(#-5), >> v(#-6), >> v(#-7), v(#-8), v(#-9), v(#-10), v(#-11) ). >> end loop. >> execute. >> >> The error message says >>>Warning # 513 >>>The subscript in a vector reference is missing or otherwise invalid. The >>>subscript must be a positive integer and must not be greater than the >length >>>of the vector. The result has been set to the system-missing value. >> >> ===================== >> 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 >> > > >-- >View this message in context: >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 ===================== 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 |
Administrator
|
Don't get your panties in a knot!!!
You obviously did *NOT* comprehend the gist of my comments (nor my posted solution). Bruce's approach should work fine (mine will to but makes SPSS do the heavy lifting). You should include the code which declares the resulting moving averages: abbreviated: NUMERIC m2010_07 TO m2010_12 m2011_01 TO m2011_12 (Fw.d). OTOH: Note that subscripts in VECTORS have to be positive (1-12 is NOT). Netiquette? I don't know, some threads require a clue stick ;-)
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?" |
Administrator
|
Here is a modified/corrected version of my solution (forgot that MA is a centered moving average), using the lead of a PMA (prior moving average) and a provisional means correction for the last case in a ID grouping.
Very simple example of how to create a general macro solution which would be rather tricky (to say nothing of unreadable) to code using the MEAN(list of subscripted vector elements) approach: data list free / x1 TO x10. BEGIN DATA 1 2 3 4 5 6 7 8 9 10 2 3 4 5 6 7 8 9 10 11 END DATA. DEFINE MAVG (VARS !CHAREND("/")/ORDER !TOKENS(1) ) VARSTOCASES MAKE Xvar FROM !VARS/ ID ID. SPLIT FILE BY ID. CREATE !CONCAT("PAVG_",!ORDER) = PMA(XVar,!ORDER)/LID=LEAD(ID,1). CREATE !CONCAT("MAV_",!ORDER)=LEAD(!CONCAT("PAVG_",!ORDER),1). IF SYSMIS(LID) !CONCAT("MAV_",!ORDER)=(!CONCAT("PAVG_",!ORDER)*!ORDER-LAG(XVAR,!ORDER) + XVAR)/!ORDER. MATCH FILES / FILE * / DROP !CONCAT("PAVG_",!ORDER) LID. CASESTOVARS ID=ID. !ENDDEFINE . SET MPRINT ON. MAVG VARS X1 TO X10 / ORDER=4.
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?" |
Administrator
|
The REALLY FUGLY wide counterpart! ;-)
I'll let ya'll stew on this one over the weekend. ------------------------------------ DEFINE MOVAVG (VARS !CHAREND ("/") / ORDER !CHAREND ("/") / MPREF !CHAREND ("/") / YRBEG !CHAREND ("/") / YREND !CHAREND ("/") / MOBEG !CHAREND ("/") / MOEND !CHAREND ("/") ). !LET !Y12="XXXXXXXXXXXX" !LET !MOX="" !DO !X=1 !TO !MOBEG !LET !MOX=!CONCAT(!MOX,"X") !DOEND !LET !MVLIST=" " !LET !ENDMO=12 !IF (!YR !EQ !YREND) !THEN !ENDMO=!MOEND !IFEND !LET !FIRST = !CONCAT(!MPREF,"_",!YRBEG,"_",!MOBEG) !LET !LAST = !CONCAT(!MPREF,"_",!YREND,"_",!MOEND) COMPUTE #NumMEAN=1. !DO !YR=!YRBEG !TO !YREND !DO !MO=!LENGTH(!MOX) !TO !ENDMO !LET !MVLIST=!CONCAT(!MVLIST,!MPREF,"_",!YR,"_",!MO," ") + COMPUTE #NumMEAN= #NumMEAN+1. !DOEND !LET !MOX="X" !DOEND !LET !MLIST="V(1)" !DO !V=2 !TO !ORDER !LET !MLIST=!CONCAT(!MLIST,",V(" , !V, ") " ) !DOEND NUMERIC !MVLIST (F8.3). VECTOR V=!VARS . VECTOR M=!FIRST TO !LAST. COMPUTE M(1)=MEAN(!MLIST). LOOP #I=2 TO #NumMean. + COMPUTE M(#I)=SUM(M(#I-1)*!ORDER, -1*V(#I-1), V(#I+!ORDER-1))/!ORDER . END LOOP. !ENDDEFINE. DATA LIST FREE / VAR1 TO VAR30. BEGIN DATA 5 3 5 6 1 3 6 1 3 5 6 1 4 3 5 1 4 5 6 3 1 4 5 3 1 5 3 1 3 6 1 4 5 3 1 5 3 1 3 6 4 7 2 6 7 4 6 2 7 8 5 3 5 6 1 3 6 1 3 5 4 6 7 2 6 4 8 7 1 6 8 8 5 2 1 2 6 3 5 6 4 6 7 2 6 4 8 7 1 6 7 1 5 6 4 7 5 1 7 6 4 5 1 7 6 5 4 7 6 1 6 1 4 3 5 1 4 5 6 3 END DATA SET MPRINT ON. MOVAVG VARS VAR1 TO VAR30 /ORDER 5/MPREF M /YRBEG 11/YREND 12 / MOBEG 7 /MOEND 12 . VAR WIDTH ALL(4). FORMAT VAR1 TO VAR30 (F1.0). EXE. -- View this message in context: http://spssx-discussion.1045642.n5.nabble.com/New-variables-as-mean-of-others-tp5490673p5495249.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
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?" |
Administrator
|
In reply to this post by David Marso
**EDITED**
The REALLY FUGLY wide counterpart! ;-) I'll let ya'll stew on this one over the weekend. ------------------------------------ DEFINE MOVAVG (VARS !CHAREND ("/") / ORDER !CHAREND ("/") / MPREF !CHAREND ("/") / YRBEG !CHAREND ("/") / YREND !CHAREND ("/") / MOBEG !CHAREND ("/") / MOEND !CHAREND ("/") ). !LET !Y12="XXXXXXXXXXXX" !LET !MOX="" !DO !X=1 !TO !MOBEG !LET !MOX=!CONCAT(!MOX,"X") !DOEND !LET !MVLIST=" " !LET !ENDMO=12 !LET !FIRST = !CONCAT(!MPREF,"_",!YRBEG,"_",!MOBEG) !LET !LAST = !CONCAT(!MPREF,"_",!YREND,"_",!MOEND) COMPUTE #NumMEAN=1. !DO !YR=!YRBEG !TO !YREND !IF (!YR !EQ !YREND) !THEN !ENDMO=!MOEND !IFEND !DO !MO=!LENGTH(!MOX) !TO !ENDMO !LET !MVLIST=!CONCAT(!MVLIST,!MPREF,"_",!YR,"_",!MO," ") + COMPUTE #NumMEAN= #NumMEAN+1. !DOEND !LET !MOX="X" !DOEND !LET !MLIST="V(1)" !DO !V=2 !TO !ORDER !LET !MLIST=!CONCAT(!MLIST,",V(" , !V, ") " ) !DOEND NUMERIC !MVLIST (F8.3). VECTOR V=!VARS . VECTOR M=!FIRST TO !LAST. COMPUTE M(1)=MEAN(!MLIST). LOOP #I=2 TO #NumMean. + COMPUTE M(#I)=SUM(M(#I-1)*!ORDER, -1*V(#I-1), V(#I+!ORDER-1))/!ORDER . END LOOP. !ENDDEFINE. DATA LIST FREE / VAR1 TO VAR30. BEGIN DATA 5 3 5 6 1 3 6 1 3 5 6 1 4 3 5 1 4 5 6 3 1 4 5 3 1 5 3 1 3 6 1 4 5 3 1 5 3 1 3 6 4 7 2 6 7 4 6 2 7 8 5 3 5 6 1 3 6 1 3 5 4 6 7 2 6 4 8 7 1 6 8 8 5 2 1 2 6 3 5 6 4 6 7 2 6 4 8 7 1 6 7 1 5 6 4 7 5 1 7 6 4 5 1 7 6 5 4 7 6 1 6 1 4 3 5 1 4 5 6 3 END DATA SET MPRINT ON. MOVAVG VARS VAR1 TO VAR30 /ORDER 5/MPREF M /YRBEG 11/YREND 12 / MOBEG 7 /MOEND 12 . VAR WIDTH ALL(4). FORMAT VAR1 TO VAR30 (F1.0). EXE.
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?" |
Free forum by Nabble | Edit this page |