Discussion:
Creating a Macro to run Compute commands
(too old to reply)
Elyse Cottrell-Martin
2019-06-05 20:31:01 UTC
Permalink
I have a lag sequence that I would like to make into a macro since I am potentially going to be using it on about 12 different variables.


This is an example of the syntax I want to make a macro:


COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.


I have looked all over the internet but am not clear if I can even do it (I would need to set "var" in the above syntax as something I can define,

So if I say var = Assess4 it would run it as:



COMPUTE Assess4_lag = lag(Assess4 ).
EXECUTE.
formats Assess4_lag(f5.0).
DO IF (AssessType=0).
RECODE Assess4_lag (ELSE=999).
END IF.
EXECUTE.
RECODE Assess4_lag (999=SYSMIS).
EXECUTE.

I tried the following:

****.

DEFINE lagging (var = !cmdend)

COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.

!ENDDEFINE.


lagging var = Assess4

****.

But I get a whole bunch of errors (Basically anywhere the var is). I've tried it with !var and !cmdend and I just get the same errors.

This is my first time using Macros (and I just started learning syntax a few weeks ago, although I've used SPSS for a few years). Any help is appreciated.
Rich Ulrich
2019-06-06 05:18:42 UTC
Permalink
On Wed, 5 Jun 2019 13:31:01 -0700 (PDT), Elyse Cottrell-Martin
Post by Elyse Cottrell-Martin
I have a lag sequence that I would like to make into a macro since I am potentially going to be using it on about 12 different variables.
COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.
I think it will be more efficient if you settle for using

COMMENT: create the variables, first. Numeric? .
COMMENT: Mix lines defining numeric and string if
+ those variables are mixed. Use STRING for alpha.

NUMERIC var1_lag, var2_lag < etc> var12_lag .

COMMENT For DO REPEAT, list var1 to var12 if they are not
+ consecutive in the file.
DO REPEAT dum1= var1 to var12 /dum2= var1_lag to var12_lag.
COMPUTE dum2= lag(dum1).
END REPEAT.

DO IF (AssessType=0).
RECODE var1_lag to var12_lag (ELSE= 999).
END IF.

RECODE var1_lag to var12_lag(999=SYSMIS).

I think that you do not need those EXECUTEs. Everything
will get done when you run a Procedure.
--
Rich Ulrich
Bruce Weaver
2019-06-06 15:36:34 UTC
Permalink
Post by Elyse Cottrell-Martin
I have a lag sequence that I would like to make into a macro since I am potentially going to be using it on about 12 different variables.
COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.
I have looked all over the internet but am not clear if I can even do it (I would need to set "var" in the above syntax as something I can define,
COMPUTE Assess4_lag = lag(Assess4 ).
EXECUTE.
formats Assess4_lag(f5.0).
DO IF (AssessType=0).
RECODE Assess4_lag (ELSE=999).
END IF.
EXECUTE.
RECODE Assess4_lag (999=SYSMIS).
EXECUTE.
****.
DEFINE lagging (var = !cmdend)
COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.
!ENDDEFINE.
lagging var = Assess4
****.
But I get a whole bunch of errors (Basically anywhere the var is). I've tried it with !var and !cmdend and I just get the same errors.
This is my first time using Macros (and I just started learning syntax a few weeks ago, although I've used SPSS for a few years). Any help is appreciated.
Rich may be right in suggesting that you don't need a macro. But given the time you've put in on it, you might like to see how to get it working. Try this:

NEW FILE.
DATASET CLOSE ALL.
DATA LIST FREE / Assess4 AssessType (2F1).
BEGIN DATA
1 1 2 1 3 1 4 1
1 0 2 0 3 0 4 0
END DATA.

DEFINE !lagging (var = !cmdend)

!LET !vlag = !CONCAT(!var,"_lag")
COMPUTE !vlag = lag(!var).
formats !vlag(f5.0).
DO IF (AssessType=0).
RECODE !vlag (ELSE=999).
MISSING VALUES !vlag(999).
END IF.
EXECUTE.

!ENDDEFINE.

* Comment out the SET commands when you know everything is working okay.
SET MPRINT ON.
!lagging var = Assess4.
SET MPRINT OFF.

LIST.

OUTPUT from LIST:

Assess4 AssessType Assess4_lag

1 1 .
2 1 1
3 1 2
4 1 3
1 0 999
2 0 999
3 0 999
4 0 999

Number of cases read: 8 Number of cases listed: 8

Notice that I got rid of your recode of 999 into SYSMIS. That is generally a bad idea. See many posts on the topic by Art Kendall in the SPSSX-L mailing list forum (http://spssx-discussion.1045642.n5.nabble.com/). Instead, I used a MISSING VALUES command to treat 999 as missing.

Given that you have a lot of variables you want to apply this macro to, the next thing to experiment with would be handing the macro a list of variables, and then making it loop through them. Take a look here for some hints:

https://www.ibm.com/support/knowledgecenter/en/SSLVMB_25.0.0/statistics_reference_project_ddita/spss/base/syn_define_list-processing_loop.html#syn_define_list-processing_loop

HTH.


HTH.
David Marso
2019-06-06 19:34:13 UTC
Permalink
DEFINE !DoLagList (VarList !CMDEND)
!DO !Var !IN (!VarList)
!Let !LagVar= !CONCAT(!Var,'_Lag')
COMPUTE !LagVar = LAG(!Var).
FORMATS !LagVar(f5.0).
IF (AssessType EQ 0) !LagVar=999.
MISSING VALUES !LagVar (999).
VALUE LABELS !LagVar 999 'Missing due to AssessType EQ 0'.
!DOEND
EXECUTE.
!ENDDEFINE.

!DoLagList VarList=x1 x2 x3 …..xK.

Best to reserve SYSMIS for 'system' missing, not for known issues.
Post by Elyse Cottrell-Martin
I have a lag sequence that I would like to make into a macro since I am potentially going to be using it on about 12 different variables.
COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.
I have looked all over the internet but am not clear if I can even do it (I would need to set "var" in the above syntax as something I can define,
COMPUTE Assess4_lag = lag(Assess4 ).
EXECUTE.
formats Assess4_lag(f5.0).
DO IF (AssessType=0).
RECODE Assess4_lag (ELSE=999).
END IF.
EXECUTE.
RECODE Assess4_lag (999=SYSMIS).
EXECUTE.
****.
DEFINE lagging (var = !cmdend)
COMPUTE var_lag = lag(var).
EXECUTE.
formats var_lag(f5.0).
DO IF (AssessType=0).
RECODE var_lag (ELSE=999).
END IF.
EXECUTE.
RECODE var_lag (999=SYSMIS).
EXECUTE.
!ENDDEFINE.
lagging var = Assess4
****.
But I get a whole bunch of errors (Basically anywhere the var is). I've tried it with !var and !cmdend and I just get the same errors.
This is my first time using Macros (and I just started learning syntax a few weeks ago, although I've used SPSS for a few years). Any help is appreciated.
Bruce Weaver
2019-06-06 20:06:13 UTC
Permalink
Post by David Marso
DEFINE !DoLagList (VarList !CMDEND)
!DO !Var !IN (!VarList)
!Let !LagVar= !CONCAT(!Var,'_Lag')
COMPUTE !LagVar = LAG(!Var).
FORMATS !LagVar(f5.0).
IF (AssessType EQ 0) !LagVar=999.
MISSING VALUES !LagVar (999).
VALUE LABELS !LagVar 999 'Missing due to AssessType EQ 0'.
!DOEND
EXECUTE.
!ENDDEFINE.
!DoLagList VarList=x1 x2 x3 …..xK.
Best to reserve SYSMIS for 'system' missing, not for known issues.
Hey David, I thought I was taking a page out of ~your~ book when I left that as an exercise for the OP! ;-)
Elyse Cottrell-Martin
2019-06-06 23:21:49 UTC
Permalink
Post by Bruce Weaver
Post by David Marso
DEFINE !DoLagList (VarList !CMDEND)
!DO !Var !IN (!VarList)
!Let !LagVar= !CONCAT(!Var,'_Lag')
COMPUTE !LagVar = LAG(!Var).
FORMATS !LagVar(f5.0).
IF (AssessType EQ 0) !LagVar=999.
MISSING VALUES !LagVar (999).
VALUE LABELS !LagVar 999 'Missing due to AssessType EQ 0'.
!DOEND
EXECUTE.
!ENDDEFINE.
!DoLagList VarList=x1 x2 x3 …..xK.
Best to reserve SYSMIS for 'system' missing, not for known issues.
Hey David, I thought I was taking a page out of ~your~ book when I left that as an exercise for the OP! ;-)
I really appreciate all the help... and since I'm new at syntax and macros I appreciate the resources which I am going to go over and learn from.

You actually got a call this afternoon Bruce (or a google chat maybe) and now we aren't even using lag anymore for our project haha. :)
Elyse Cottrell-Martin
2019-06-10 15:12:33 UTC
Permalink
We ended up using the lag macro for a different aspect of the data so it was extremely helpful!
Post by Elyse Cottrell-Martin
Post by Bruce Weaver
Post by David Marso
DEFINE !DoLagList (VarList !CMDEND)
!DO !Var !IN (!VarList)
!Let !LagVar= !CONCAT(!Var,'_Lag')
COMPUTE !LagVar = LAG(!Var).
FORMATS !LagVar(f5.0).
IF (AssessType EQ 0) !LagVar=999.
MISSING VALUES !LagVar (999).
VALUE LABELS !LagVar 999 'Missing due to AssessType EQ 0'.
!DOEND
EXECUTE.
!ENDDEFINE.
!DoLagList VarList=x1 x2 x3 …..xK.
Best to reserve SYSMIS for 'system' missing, not for known issues.
Hey David, I thought I was taking a page out of ~your~ book when I left that as an exercise for the OP! ;-)
I really appreciate all the help... and since I'm new at syntax and macros I appreciate the resources which I am going to go over and learn from.
You actually got a call this afternoon Bruce (or a google chat maybe) and now we aren't even using lag anymore for our project haha. :)
Loading...