在宏中循环遍历SPSS变量的值



如何将特定变量的值传递给宏中的列表处理循环?

假设,作为一个简化的例子,我有一个变量foo,它包含值1,4,12,33和51。
DATA LIST FREE / foo (F2) .
BEGIN DATA
1 
4 
12 
33 
51 
END DATA.

和一个用这些值做一些事情的宏。

出于测试的原因,这个宏将只是回显这些值。我想找到一种方法来运行一个像这样工作的例程:

DEFINE !testmacro (list !CMDEND)
   !DO !i !IN (!list)
     ECHO !QUOTE(!i).
   !DOEND.
!ENDDEFINE.
!testmacro list = 1 4 12 33 51. * <- = values from foo.

在这种情况下,使用Python api将是一个不错的选择。

我最近对Python有点熟悉了:-)这就是我算出来的。

如果变量是数字:

BEGIN PROGRAM PYTHON.
import spss,spssdata
foolist = [element[0] for element in spssdata.Spssdata('foo').fetchall()]
foostring = " ".join(str(int(i)) for i in foolist)
spss.Submit("!testmacro list = %(foostring)s." %locals())
END PROGRAM.

如果变量是字符串:

BEGIN PROGRAM PYTHON.
import spss,spssdata
foolist = [element[0].strip() for element in spssdata.Spssdata('bar').fetchall()]
foostring = " ".join(foolist)
spss.Submit("!testmacro list = %(foostring)s." %locals())
END PROGRAM.
变异

删除重复项,列表为有序

BEGIN PROGRAM PYTHON.
import spss,spssdata
foolist = sorted(set([element[0] for element in spssdata.Spssdata('foo').fetchall()]))
foostring = " ".join(str(int(i)) for i in foolist)
spss.Submit("!testmacro list = %(foostring)s." %locals())
END PROGRAM.

按数据集中首次出现的顺序删除重复项和项

这里,我使用了一个函数,我从Peter Bengtsson的主页(peterbe.com)检索

BEGIN PROGRAM PYTHON.
import spss,spssdata
def uniquify(seq, idfun=None): 
   # order preserving
   if idfun is None:
       def idfun(x): return x
   seen = {}
   result = []
   for item in seq:
       marker = idfun(item)
       if marker in seen: continue
       seen[marker] = 1
       result.append(item)
   return result
foolist = uniquify([element[0] for element in spssdata.Spssdata('foo').fetchall()])
foostring = " ".join(str(int(i)) for i in foolist)
spss.Submit("!testmacro list = %(foostring)s." %locals())
END PROGRAM.
<<h2>非python解决方案/h2>

并不是我推荐它,但甚至有一种不需要Python就能做到的方法。我从SPSS编程书中获得了基本的想法,内容如下:使用WRITE命令创建一个包含所需命令和变量值的文本文件,并将其包含在插入命令中。

DATASET COPY foolistdata.
DATASET ACTIVATE foolistdata.
AGGREGATE OUTFILE=* MODE=ADDVARIABLES
   /BREAK
   /NumberOfCases=N.
* Variable which contains the command as string in the first case.
STRING macrocommand (A18).
IF ($casenum=1) macroCommand = "!testmacro list = ".
EXECUTE.
* variable which contains a period (.) in the last case, 
* for the ending of the command string. 
STRING commandEnd (A1).
IF ($casenum=NumberOfCases) commandEnd = ".".
* Write the 'table' with the command and variable values into a textfile.
WRITE OUTFILE="macrocommand.txt" /macrocommand bar commandEnd.
EXECUTE.
* Macrocall.
INSERT FILE ="macrocommand.txt".

最新更新