SPSS 不会在 Python 中打开数据集
SPSS won't open dataset in Python
我正在尝试使用 python 脚本来操作 SPSS 数据集。问题是,我的代码不会打开活动数据集。有问题的部分是:
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
如果我手动打开 .sav 文件和 运行 代码,此代码将创建一个数据集对象。但是在我的程序中,它只是创建了一个空数据集,即使我显然有一个活动数据集 运行ning。我该如何解决这个问题?
这是错误:
Traceback (most recent call last):
File "<string>", line 128, in <module>
ValueError: __len__() should return >= 0
BEGIN PROGRAM.
import SpssClient,spssaux, spss, os
SpssClient.StartClient()
path='c:\users\myDocs\'
def inlezen(path,filename):
if filename.startswith("Dec_gemeente"):
vars=' /1 Code1 0-3 A4 Label1 4-33 A30'
if filename.startswith("Dec_post"):
vars=' /1 Code1 0-3 A4 Label1 4-27 A24 Code2 28-32 A5 Label2 33-67 A35'
if filename.startswith("Dec_etniciteit_kort"):
vars=' /1 Code1 0-0 A1 Label1 1-23 A23'
if filename.startswith("Dec_etniciteit_lang"):
vars=' /1 Code1 0-1 A2 Label1 2-33 A32 Code2 34-34 A1 Label2 35-58 A24 Code3 59-59 A1 Label3 60-95 A36'
if filename.startswith("Dec_geslacht"):
vars= ' /1 Code1 0-0 A1 Label1 1-8 A8'
if filename.startswith("Dec_landcode"):
vars=' /1 Code1 0-3 A4 Label1 4-43 A40 Code2 44-44 A1 Label2 45-56 A12 Code3 57-58 A2 Label3 59-89 A31'
if filename.startswith("Dec_nationaliteit"):
vars=' /1 Code1 0-3 A4 Label1 4-43 A40 Code2 44-44 A1 Label2 45-56 A12 Code3 57-58 A2 Label3 59-89 A31'
if filename.startswith("Dec_verbl"):
vars=' /1 Code1 0-1 A2 Label1 2-84 A83'
bestand=path+filename
spss.Submit("""
DATASET CLOSE ALL.
GET DATA
/TYPE=TXT
/FILE='%s'
/FIXCASE=1
/ARRANGEMENT=FIXED
/FIRSTCASE=1
/IMPORTCASE=ALL
/VARIABLES=%s.
DATASET NAME LabelSet WINDOW=FRONT.
DATASET ACTIVATE LabelSet.
EXECUTE."""
%(bestand,vars))
def wegschrijven(filename):
labels1=''
labels2=''
labels3=''
# Labels maken 1.
varnaam=filename
labels1='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(2):
if j==0:
temp=str(dataset.cases[i, j])[2:-2]
labels1 = labels1 + '\n' + temp + ' '
if j==1:
temp=str(dataset.cases[i, j])[2:-2]
labels1 = labels1 + "'" + temp + "'"
labels1=labels1+'.'
try:
# Labels maken 2.
varnaam='test'
labels2='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(2,4):
if j==2:
temp=str(dataset.cases[i, j])[2:-2]
labels2 = labels2 + '\n' + temp + ' '
if j==3:
temp=str(dataset.cases[i, j])[2:-2]
labels2 = labels2 + "'" + temp + "'"
labels2=labels2+'.'
except:
labels2=''
print 'geen var 2'
try:
# Labels maken 3.
varnaam='test'
labels3='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(4,6):
if j==4:
temp=str(dataset.cases[i, j])[2:-2]
labels3 = labels3 + '\n' + temp + ' '
if j==5:
temp=str(dataset.cases[i, j])[2:-2]
labels3 = labels3 + "'" + temp + "'"
labels3=labels3+'.'
except:
labels3=''
print 'geen var 3'
output= labels1 + '\n' + '\n' + labels2 + '\n' + '\n' + labels3
print output
# Output naar syntaxdoc schrijven
NewSyntaxDoc = SpssClient.NewSyntaxDoc()
NewSyntaxDoc.SetAsDesignatedSyntaxDoc()
# Inhoud syntax wijzigen.
NewSyntaxDoc.SetSyntax(output)
# Syntaxdocument opslaan.
pad='I:/geg/WON/1 cijfer/LABELS/spsfiles/Labelbestanden/'+filename+'.sps'
NewSyntaxDoc.SaveAs(pad)
for root, dirs, files in os.walk(path):
for filename in files:
inlezen(path,filename)
# Toegang krijgen tot data editor.
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
# Wegschrijven labels naar .sps.
wegschrijven(filename)
dataset.close()
spss.EndDataStep()
END PROGRAM.
以下对我来说效果很好(它给出了一个打印回,确认活动数据集中有 474 个案例):
begin program.
import spss
spss.Submit(r"""
get file="C:/Program Files/IBM/SPSS/Statistics/23/Samples/English/Employee data.sav".
""")
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
end program.
我假设是代码行 for root, dirs, files in os.walk(path):
在您的代码中有问题,特别是它正在选择的文件,然后尝试 运行 剩余的代码。尝试 debugging/assesing 到底循环了哪些文件...
好的,经过一天的激烈尝试,我想出了一个解决方法。
显然,GET DATA 命令没有正确地将数据集加载到内存中。我添加了一个 SAVE OUTFILE 和 GET FILE 命令,现在它工作正常。
这是我的解决方案:
spss.Submit("""
DATASET CLOSE ALL.
GET DATA
/TYPE=TXT
/FILE='%s'
/FIXCASE=1
/ARRANGEMENT=FIXED
/FIRSTCASE=1
/IMPORTCASE=ALL
/VARIABLES=%s.
DATASET NAME LabelSet WINDOW=FRONT.
DATASET ACTIVATE LabelSet.
EXECUTE."""
%(bestand,vars))
spss.Submit("""SAVE OUTFILE ='c:\user\myDocs\TEMP.sav'.
GET FILE ='c:\user\myDocs\TEMP.sav'.""")
这会将数据集正确加载到内存中。我仍然认为这是 SPSS 的奇怪和不直观的行为。感谢您的回答。它让我朝着正确的方向前进。
这对我来说也很好用:
begin program.
import spss
spss.Submit(r"""
GET DATA
/TYPE=XLS
/FILE='C:\Program Files\IBM\SPSS\Statistics\Samples\English\demo.xls'
/SHEET=name 'demo'
/CELLRANGE=full
/READNAMES=on
/ASSUMEDSTRWIDTH=32767.
""")
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
end program.
我在打开 Excel 文件的情况下调用 GET DATA
进行了测试,它工作正常。我不相信 GET DATA
您的代码有问题。我会进行更多彻底的测试,以确保它在所有情况下都能正常工作,您的解决方案。
原始代码中的一个潜在问题是未受保护的表达式 path='c:\users\myDocs\' 在 Python 中,反斜杠表达式许多表示转义序列并被转换为它们所代表的内容,这将是不幸的路径。使用正斜杠或以 r 开头,如 path=r'c:\users\myDocs\'。在这种情况下你很幸运,但迟早会被抓到。
至于 GET DATA,除非必要,否则它不会读取整个文件 - EXECUTE 语句将强制执行此操作,但这不应影响数据集的存在。但是,只有在读取整个文件后才能知道案例的数量。
我正在尝试使用 python 脚本来操作 SPSS 数据集。问题是,我的代码不会打开活动数据集。有问题的部分是:
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
如果我手动打开 .sav 文件和 运行 代码,此代码将创建一个数据集对象。但是在我的程序中,它只是创建了一个空数据集,即使我显然有一个活动数据集 运行ning。我该如何解决这个问题?
这是错误:
Traceback (most recent call last):
File "<string>", line 128, in <module>
ValueError: __len__() should return >= 0
BEGIN PROGRAM.
import SpssClient,spssaux, spss, os
SpssClient.StartClient()
path='c:\users\myDocs\'
def inlezen(path,filename):
if filename.startswith("Dec_gemeente"):
vars=' /1 Code1 0-3 A4 Label1 4-33 A30'
if filename.startswith("Dec_post"):
vars=' /1 Code1 0-3 A4 Label1 4-27 A24 Code2 28-32 A5 Label2 33-67 A35'
if filename.startswith("Dec_etniciteit_kort"):
vars=' /1 Code1 0-0 A1 Label1 1-23 A23'
if filename.startswith("Dec_etniciteit_lang"):
vars=' /1 Code1 0-1 A2 Label1 2-33 A32 Code2 34-34 A1 Label2 35-58 A24 Code3 59-59 A1 Label3 60-95 A36'
if filename.startswith("Dec_geslacht"):
vars= ' /1 Code1 0-0 A1 Label1 1-8 A8'
if filename.startswith("Dec_landcode"):
vars=' /1 Code1 0-3 A4 Label1 4-43 A40 Code2 44-44 A1 Label2 45-56 A12 Code3 57-58 A2 Label3 59-89 A31'
if filename.startswith("Dec_nationaliteit"):
vars=' /1 Code1 0-3 A4 Label1 4-43 A40 Code2 44-44 A1 Label2 45-56 A12 Code3 57-58 A2 Label3 59-89 A31'
if filename.startswith("Dec_verbl"):
vars=' /1 Code1 0-1 A2 Label1 2-84 A83'
bestand=path+filename
spss.Submit("""
DATASET CLOSE ALL.
GET DATA
/TYPE=TXT
/FILE='%s'
/FIXCASE=1
/ARRANGEMENT=FIXED
/FIRSTCASE=1
/IMPORTCASE=ALL
/VARIABLES=%s.
DATASET NAME LabelSet WINDOW=FRONT.
DATASET ACTIVATE LabelSet.
EXECUTE."""
%(bestand,vars))
def wegschrijven(filename):
labels1=''
labels2=''
labels3=''
# Labels maken 1.
varnaam=filename
labels1='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(2):
if j==0:
temp=str(dataset.cases[i, j])[2:-2]
labels1 = labels1 + '\n' + temp + ' '
if j==1:
temp=str(dataset.cases[i, j])[2:-2]
labels1 = labels1 + "'" + temp + "'"
labels1=labels1+'.'
try:
# Labels maken 2.
varnaam='test'
labels2='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(2,4):
if j==2:
temp=str(dataset.cases[i, j])[2:-2]
labels2 = labels2 + '\n' + temp + ' '
if j==3:
temp=str(dataset.cases[i, j])[2:-2]
labels2 = labels2 + "'" + temp + "'"
labels2=labels2+'.'
except:
labels2=''
print 'geen var 2'
try:
# Labels maken 3.
varnaam='test'
labels3='VAR LAB' + ' ' + varnaam + " '" + varnaam + "'" + '.' + '\n' + 'VAL LAB'+' '+varnaam
for i in range(len(dataset.cases)):
for j in range(4,6):
if j==4:
temp=str(dataset.cases[i, j])[2:-2]
labels3 = labels3 + '\n' + temp + ' '
if j==5:
temp=str(dataset.cases[i, j])[2:-2]
labels3 = labels3 + "'" + temp + "'"
labels3=labels3+'.'
except:
labels3=''
print 'geen var 3'
output= labels1 + '\n' + '\n' + labels2 + '\n' + '\n' + labels3
print output
# Output naar syntaxdoc schrijven
NewSyntaxDoc = SpssClient.NewSyntaxDoc()
NewSyntaxDoc.SetAsDesignatedSyntaxDoc()
# Inhoud syntax wijzigen.
NewSyntaxDoc.SetSyntax(output)
# Syntaxdocument opslaan.
pad='I:/geg/WON/1 cijfer/LABELS/spsfiles/Labelbestanden/'+filename+'.sps'
NewSyntaxDoc.SaveAs(pad)
for root, dirs, files in os.walk(path):
for filename in files:
inlezen(path,filename)
# Toegang krijgen tot data editor.
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
# Wegschrijven labels naar .sps.
wegschrijven(filename)
dataset.close()
spss.EndDataStep()
END PROGRAM.
以下对我来说效果很好(它给出了一个打印回,确认活动数据集中有 474 个案例):
begin program.
import spss
spss.Submit(r"""
get file="C:/Program Files/IBM/SPSS/Statistics/23/Samples/English/Employee data.sav".
""")
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
end program.
我假设是代码行 for root, dirs, files in os.walk(path):
在您的代码中有问题,特别是它正在选择的文件,然后尝试 运行 剩余的代码。尝试 debugging/assesing 到底循环了哪些文件...
好的,经过一天的激烈尝试,我想出了一个解决方法。
显然,GET DATA 命令没有正确地将数据集加载到内存中。我添加了一个 SAVE OUTFILE 和 GET FILE 命令,现在它工作正常。
这是我的解决方案:
spss.Submit("""
DATASET CLOSE ALL.
GET DATA
/TYPE=TXT
/FILE='%s'
/FIXCASE=1
/ARRANGEMENT=FIXED
/FIRSTCASE=1
/IMPORTCASE=ALL
/VARIABLES=%s.
DATASET NAME LabelSet WINDOW=FRONT.
DATASET ACTIVATE LabelSet.
EXECUTE."""
%(bestand,vars))
spss.Submit("""SAVE OUTFILE ='c:\user\myDocs\TEMP.sav'.
GET FILE ='c:\user\myDocs\TEMP.sav'.""")
这会将数据集正确加载到内存中。我仍然认为这是 SPSS 的奇怪和不直观的行为。感谢您的回答。它让我朝着正确的方向前进。
这对我来说也很好用:
begin program.
import spss
spss.Submit(r"""
GET DATA
/TYPE=XLS
/FILE='C:\Program Files\IBM\SPSS\Statistics\Samples\English\demo.xls'
/SHEET=name 'demo'
/CELLRANGE=full
/READNAMES=on
/ASSUMEDSTRWIDTH=32767.
""")
spss.StartDataStep()
dataset = spss.Dataset()
print len(dataset.cases)
end program.
我在打开 Excel 文件的情况下调用 GET DATA
进行了测试,它工作正常。我不相信 GET DATA
您的代码有问题。我会进行更多彻底的测试,以确保它在所有情况下都能正常工作,您的解决方案。
原始代码中的一个潜在问题是未受保护的表达式 path='c:\users\myDocs\' 在 Python 中,反斜杠表达式许多表示转义序列并被转换为它们所代表的内容,这将是不幸的路径。使用正斜杠或以 r 开头,如 path=r'c:\users\myDocs\'。在这种情况下你很幸运,但迟早会被抓到。
至于 GET DATA,除非必要,否则它不会读取整个文件 - EXECUTE 语句将强制执行此操作,但这不应影响数据集的存在。但是,只有在读取整个文件后才能知道案例的数量。