循环遍历宏内的SPSS变量的值

时间:2014-08-07 21:42:42

标签: macros 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.

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:2)

我最近对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's Homepage (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.

非Python解决方案

不是我推荐它,但是如果没有Python,甚至有办法做到这一点。 我从SPSS编程书中得到了基本的想法,如下: 使用WRITE命令创建包含所需命令和变量值​​的文本文件,并将其包含在insert命令中。

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".