SPSS-Python 当 spss.Submit() 中的 spss 命令产生警告时,脚本停止并出现错误

SPSS-Python Script stops with an Error when spss commands inside spss.Submit() would create a warning

假设我有两个变量列表

list a: a1 a2 a3
list b: b1 b2 b3

我想以这样的方式处理:

TEMPORARY.
SELECT IF a1=b1.
FREQUENCY someVar.


TEMPORARY.
SELECT IF a2=b2.
FREQUENCY someVar.


TEMPORARY.
SELECT IF a2=b2.
FREQUENCY someVar.

我尝试在 python 循环中执行此操作:

BEGIN PROGRAM.
import spss

la = ['a1', 'a2', 'a3']
lb = ['b1', 'b2', 'b3']

for a, b in zip(la, lb):
    spss.Submit('''
TEMPORARY.
SELECT IF %s=%s.
FREQUENCY someVar.
    ''' % (a, b))
END PROGRAM.

到目前为止一切顺利。这有效,除非 SELECT IF 命令会创建一个空数据集。在 Python 程序块之外,这会导致输出查看器中出现以下警告消息:

No cases were input to this procedure. Either there are none in the working data file or all of them have been filtered out. Execution of this command stops.

但是在 Python 块内它会导致错误并且 python 脚本停止。

Traceback (most recent call last):
File "", line 7, in
File "C:\PROGRA~1\ibm\SPSS\STATIS~1\Python\Lib\site-packages\spss\spss.py", line 1527, in Submit raise SpssError,error spss.errMsg.SpssError: [errLevel 3] Serious error.

有没有办法在 python 中 运行 这个循环(可能会产生临时的空数据集,因此会产生警告)?

是的,如果您将有问题的函数包装在 try-except 结构中:

for a, b in zip(la, lb):
    try:
        spss.Submit('''
TEMPORARY.
SELECT IF %s=%s.
FREQUENCY someVar.
        ''' % (a, b))
    except:
        pass

你也可以使用PythonAPI来计算ai=bi的情况,并据此执行条件块。

因此,例如,如果只剩下不到 5 个有效案例,您可能不想生成任何输出(或者某些输出表明由于基数较小而没有生成任何输出)。如果剩余不到 50 个案例,那么您可能需要 运行 频率,如果超过 50 个案例,则 运行 描述等。有多种方法可以获取案例计数,哪种方法最好和最有效可能取决于您的数据集和最终目标。

例如: spss.GetCaseCount

Here's 另一种方法,您可以从活动数据集中获取案例计数,如统计数据,以激发更多想法。

添加一些解释:统计语法错误的相关严重级别在 1(最低)和 5 之间。您可能永远不会看到 5,因为这意味着系统已经着火了。当通过提交来自 Python 的 运行 语法时,级别 1 和 2 错误,即不会停止来自 运行 的语法的警告,将正常执行。 3 级及更高级别引发异常。您可以按照上面的建议通过 try/except 机制处理 Python 代码中的那些。

我尝试了 SET MXWARNS,但是无论将其设置为零,还是将其设置为非常高的值(例如 1000000)都不起作用。警告仍然转换为错误。所以我写了这个解决方法:

import codecs
import re
import sys

import spss
from spssaux import getShow

def submit_syntax(sps_filename):
    output_on = spss.IsOutputOn()
    spss.SetOutput("off")
    unicode_mode = getShow("unicode") == u"Yes"
    encoding = "utf-8-sig" if unicode_mode else getShow("locale").split(u".")[-1]
    if output_on:
        spss.SetOutput("on")

    with codecs.open(sps_filename, encoding=encoding) as f:
        syntax = f.read()
    statements = re.split(ur"\. *\r\n", syntax, flags=re.MULTILINE)
    for stmtno, statement in enumerate(statements, 1):
        if statement.startswith(u"*"):
            continue
        try:
            spss.Submit(statement)
        except spss.SpssError:
            # "no cases were input" warnings are translated into errors.
            if not spss.GetCaseCount() and spss.GetLastErrorLevel() <= 3:
                continue
            msg = u"ERROR in statement #%d: %s [%s]"
            raise RuntimeError(msg % (stmtno, statement, sys.exc_info()[1]))