Search code examples
spss

dynamically create variable names in loops - SPSS


I have a lot of variables with names like

PRE_adam
POST_adam
PRE_betty
POST_betty
PRE_clara
POST_clara
...

for a lot of people's names.

I want to calculate the difference between PRE_X and POST_X for a list of Xs - something like this:

COMPUTE DIFF_adam = POST_adam - PRE_adam
COMPUTE DIFF_betty = POST_betty - PRE_betty
COMPUTE DIFF_clara = POST_clara - PRE_clara

is there a way to do this in a loop? Something like this:

DO REPEAT x= adam betty clara
COMPUTE !concat('DIFF_',x) = !concat('POST_',x) - !concat('PRE_',x)
END REPEAT

Solution

  • You are mistakenly trying to use SPSS's macro language (DEFINE / !ENDDEFINE) in normal SPSS syntax i.e. !concat works only when used in the body of a SPSS macro.

    Here is a solution non-python solution using DEFINE/!ENDDEFINE: But which requires the input of the names.

    /*** ############################## ***/.
    DATA LIST FREE/ PRE_adam
    POST_adam
    PRE_betty
    POST_betty
    PRE_clara
    POST_clara.
    BEGIN DATA
    1 3 15 27 19 31
    2 4 16 18 20 42
    END DATA.
    /*** ############################## ***/.
    
    
    /*** ############################## ***/.
    define !CompDiff (names=!cmdend)
    !do !i !in (!names)
      compute !concat("DIFF_",!i)=!concat('POST_',!i) - !concat('PRE_',!i).
    !doend
    exe.
    !enddefine.
    /*** ############################## ***/.
    
    
    set mprint on.
    !CompDiff names=adam betty clara.
    

    Here's a more "dynamic" solution which reads the PRE and POST vars in the active dataset and computes the difference automatically but depends on python installation setup:

    begin program.
    import spss, spssaux, spssdata
    spss.Submit("set mprint on.")
    preVars=spssaux.VariableDict(pattern="PRE",caseless=True).variables
    postVars=spssaux.VariableDict(pattern="POST",caseless=True).variables
    
    if len(preVars) != len(preVars): 
        raise ValueError("Mis-match number of PRE and POST vars")
    
    for preVar, postVar in zip(sorted(preVars),sorted(postVars)):
        preName=preVar[preVar.index("_")+1:]
        postName=postVar[postVar.index("_")+1:]
        if preName != postName:
            raise ValueError("Mis-match NAMES of PRE and POST vars")
        spss.Submit("compute DIFF_%(preName)s=POST_%(preName)s - PRE_%(preName)s." % locals())
    
    spss.Submit("set mprint off.")
    end program.