我想编写一个SPSS宏来执行三个操作:
如您所知,SPSS宏工具允许使用两种类型的循环:“数字”(如[!do !i = !x !to !y
)和“列表” /“对于每个循环”(如[!do !i !in (!1)
)。我的目标是通过调用创建一个宏,如下所示:col v1 v2 / "Sheet A" "Sheet B".
以这种方式工作(带有“列表”之类的循环):
ctables
宏部分中output export
宏部分中依此类推。
起初我写了这个:
define col (!positional !charend('/')
/!positional !cmdend)
!do !i !in (!1)
output close all.
ctables
/table x1 + x2
by !i [mean f1.2, totals[mean f1.2]].
output modify
/select logs headings texts warnings pagetitles outlineheaders notes
/deleteobject delete = yes.
!doend
!do !i !in (!2)
output export
/contents export = visible
/xlsx documentfile = "E:\path\file.xlsx"
operation = createsheet
sheet = !i.
!doend
!enddefine.
*** MACRO CALL.
col v1 v2 / "Sheet A" "Sheet B".
输出总体上是不正确的,因为我只获得了带有第二个变量的表。但是,在文件中,我发现了两张名称正确的表。因此,我尝试了嵌套:
define col (!positional !charend('/')
/!positional !cmdend)
!do !i !in (!1)
!do !j !in (!2)
output close all.
ctables
/table x1 + x2
by !i [mean f1.2, totals[mean f1.2]].
output modify
/select logs headings texts warnings pagetitles outlineheaders notes
/deleteobject delete = yes.
output export
/contents export = visible
/xlsx documentfile = "E:\path\file.xlsx"
operation = createsheet
sheet = !j.
!doend
!doend
!enddefine.
*** MACRO CALL.
col v1 v2 / "Sheet A" "Sheet B".
输出是完全相同的,这意味着SPSS将'/'左侧列表中的每个元素与'/'右侧列表中的每个元素相交,并覆盖Excel文件中的先前结果。我的目标是接收这样的宏扩展:
* FIRST EXPANSION:
...
ctables
/table x1 + x2
by v1 [mean f1.2, totals[mean f1.2]].
...
output export
/contents export = visible
/xlsx documentfile = "E:\path\file.xlsx"
operation = createsheet
sheet = "Sheet A".
* SECOND (LAST) EXPANSION:
...
ctables
/table x1 + x2
by v2 [mean f1.2, totals[mean f1.2]].
...
output export
/contents export = visible
/xlsx documentfile = "E:\path\file.xlsx"
operation = createsheet
sheet = "Sheet B".
换句话说-2列出了x 2个元素,但只有两个循环-而不是四个。有谁知道如何获得这样的结果?
编辑: +第三种解决方法
据我所知,没有正式/直接的方法可以在SPSS宏中的并行列表上运行循环,因此,您的选择是-使用Python或找到解决方法-以下是一些想法:
1。使用数字循环重新创建两个列表因此您循环使用数字1到5,并使用它们来创建变量名称-从v1到v5,从“工作表1”到“工作表5”:
!do !i=1 !to 5
.....
by !concat("v",!i) [mean f1.2, totals[mean f1.2]].
.....
sheet = !quote(!concat("sheet ",!i))
.....
!doend
如果它们不是常数,也可以将其开头和/或结尾号添加到宏调用中。当然,仅当您的两个列表共享相同的编号(如上例)时,此方法才有效。如果没有,则可以使用以下之一:
2。循环浏览一个列表,同时“吃饱”第二个列表SPSS宏循环仅一次遍历一个列表-而不是遍历第二个列表,您可以获取一个项目,并针对第一个列表的每次迭代将其从第二个列表中删除:
define col (!pos !charend('/') / !pos !cmdend)
!let !arr2=!2
!do !i !in(!1)
.....
by !i [mean f1.2, totals[mean f1.2]].
.....
!let !sheet=!head(!arr2)
!let !arr2=!tail(!arr2)
.....
sheet = !sheet
.....
!doend
!enddefine.
*and the macro call:
col VARa VARb VARc/"sheet 1" "sheet 2" "sheet 3".
3。在一对上定义宏,使用多个宏调用这是最简单的方法,如果每个列表中只有几个项目-您可以使用一个变量名和一个工作表名称定义宏,则可以通过运行-
获得相同的结果col VARa/ "sheet 1" .
col VARb/ "sheet 2" .
代替您之前尝试的col VARa VARb/ "sheet 1" "sheet 2" .
。
如果这些列表很长,您可以分别自动运行宏调用(例如,使用write
命令-但这是一个单独的问题)。