我想创建一个表,使得行和列是我的变量,每个单元格显示两个相交变量的公共值的数量。
例如,我有以下带有值的变量。
x y z
--- --- ---
* b #
g # i
# * l
+ k
m
请注意,*和#在某些变量中很常见。 x和z之间只有一个共同的值(即#),因此单元格(x,z)将为1。完整的表格如下所示。
x y z
--- --- ---
x | 4 2 1
y | 2 5 1
z | 1 1 3
如何使用SPSS进行操作以及描述此问题的关键字是什么。
答案 0 :(得分:2)
有一种使用宏语言的解决方案。
*** Set the work directory.
cd "C:\temp".
*** Define the list of variable names.
* You can make it using Utilities / Variables... command.
define !varl() x y z !end.
*** Generate the test data.
data list free
/x (a1) y (a1) z (a1).
begin data
* b #
g # i
# * l
+ k ""
"" m ""
end data.
save out "data.sav".
*** Open each variable in a new data file, drop blanks, sort and save.
define !get_sort_save(x = !cmdend)
!do !var !in (!x)
get "data.sav"
/keep !var.
sel if !var <> "".
sort cases by !var.
save out !quote(!con(!var, ".sav")).
!doend
!end.
* Run.
!get_sort_save x = !varl.
*** Match each variable with all other variables and count the matched cases.
define !match_count(x = !cmdend)
!do !var1 !in (!x)
get !quote(!con(!var1, ".sav"))
/ren !var1 = id.
!do !var2 !in (!x)
match files
/file = *
/table = !quote(!con(!var2, ".sav"))
/ren !var2 = id
/in !var2
/by id.
!doend
agg out *
/!x = sum(!x).
form !x (f8).
save out !quote(!con(!var1, "_n.sav")).
!doend
!end.
* Run.
!match_count x = !varl.
*** Add the counts.
define !add(x = !cmdend)
add files
!do !var !in (!x)
/file = !quote(!con(!var, "_n.sav"))
!doend.
!end.
* Run.
!add x = !varl.
list.
结果是
x y z
4 2 1
2 5 1
1 1 3
Number of cases read: 3 Number of cases listed: 3
这是在真实数据上运行的代码。数据必须保存在数据文件中。代码中有三个位置需要进行更改。它们标有TASK1,TASK2和TASK3。
*** TASK1 - set the work directory - the directory where the data file is saved.
cd "C:\temp".
*** TASK2 - Define the list of variable names.
define !varl() x y z !end.
*** Open each variable in a new data file, drop blanks, sort and save.
define !get_sort_save(x = !cmdend)
!do !var !in (!x)
*** TASK3 - change the file name.
get "data.sav"
/keep !var.
sel if !var <> "".
sort cases by !var.
save out !quote(!con(!var, ".sav")).
!doend
!end.
* Run.
!get_sort_save x = !varl.
*** Match each variable with all other variables and count the matched cases.
define !match_count(x = !cmdend)
!do !var1 !in (!x)
get !quote(!con(!var1, ".sav"))
/ren !var1 = id.
!do !var2 !in (!x)
match files
/file = *
/table = !quote(!con(!var2, ".sav"))
/ren !var2 = id
/in !var2
/by id.
!doend
agg out *
/!x = sum(!x).
form !x (f8).
save out !quote(!con(!var1, "_n.sav")).
!doend
!end.
* Run.
!match_count x = !varl.
*** Add the counts.
define !add(x = !cmdend)
add files
!do !var !in (!x)
/file = !quote(!con(!var, "_n.sav"))
!doend.
!end.
* Run.
!add x = !varl.
list.
答案 1 :(得分:1)
这是一个挑战 - 所以这是我尝试以合理的格式编写代码。首先,让我们创建一个看起来像你的数据集。
DATA LIST FREE / x y z (3A1).
BEGIN DATA
* b #
g # i
# * l
+ k ""
"" m ""
END DATA.
现在我做的是制作一个符号列表,然后是一个虚拟变量信号,如果该符号包含在原始变量中。
VARSTOCASES /MAKE V from x TO z /INDEX OrigVar (V).
SORT CASES BY V OrigVar.
CASESTOVARS /ID = V /VIND ROOT = "D" /INDEX = OrigVar.
您将看到数据现在如下所示:
V Dx Dy Dz
- -- -- --
* 1 1 0
# 1 1 1
+ 1 0 0
b 0 1 0
g 1 0 0
i 0 0 1
k 0 1 0
l 0 0 1
m 0 1 0
现在,如果您将Dx
和Dy
相乘,然后将计算两个集合交集的列相加。在这里,我创建一个宏来轻松计算列表中的所有乘法。 (不幸的是,你不能在这里使用TO
约定,你需要在这个宏上列出你的使用应用程序的所有25个变量。)
DEFINE !PairInter (!POSITIONAL = !CMDEND).
!DO !I !IN (!1)
!DO !J !IN (!1)
COMPUTE !CONCAT(!I,"_",!J) = !I*!J.
FORMATS !CONCAT(!I,"_",!J) (F3.0).
!DOEND
!DOEND
!ENDDEFINE.
!PairInter Dx Dy Dz.
您将看到现在有一个变量列表Dx_Dx Dx_Dy Dx_Dz Dy_Dx ..... Dz_Dz
,它们是这些变量的完整交互集。我故意写了多余的交互,因为它使得表格在以后变得更容易(尽管我可能建议在显示表格时只显示下半部分)。
所以现在如果我们对列进行求和,我们将得到每个集合的基数及其交集。在这里,我使用LAG
并将最终值保留在数据集中。
DO REPEAT D = Dx_Dx TO Dz_Dz.
IF ($casenum<>1) D = LAG(D) + D.
END REPEAT.
COMPUTE Order = $casenum.
SORT CASES BY Order (D).
SELECT IF ($casenum = 1).
MATCH FILES FILE = * /DROP V TO Dz Order.
EXECUTE.
现在,您可以编写MATRIX
过程来重塑数据集并以更好的格式打印出表格。这里我FLIP
数据集,然后获取原始变量名称。
STRING I (A1).
COMPUTE I = "I".
FLIP /NEWNAMES = I.
RENAME VARIABLES (CASE_LBL = V).
COMPUTE V = CHAR.SUBSTR(V,LENGTH(V)).
EXECUTE.
MATRIX.
GET I /FILE = * /VARIABLE = I.
GET V /FILE = * /VARIABLE = V.
COMPUTE I2 = RESHAPE(I,3,3).
COMPUTE V2 = V(1:3).
PRINT I2 /RNAMES =V2 /CNAMES = V2.
END MATRIX.
然后打印的MATRIX
语句会读取您想要的交叉表。
Run MATRIX procedure:
I2
x y z
x 4 2 1
y 2 5 1
z 1 1 3
------ END MATRIX -----
我把它变成了一个宏,可用here。定义宏后,您只需运行
即可 !InterSet x y z.
它将打印表格。
答案 2 :(得分:1)
这是一个简单的Python解决方案。它会创建一个包含计数的数据透视表。
DATA LIST FREE / x (A1) y (A5) z (A8).
BEGIN DATA
* b #
g # i
# * l
+ k ""
"" m ""
END DATA.
begin program.
import spss, spssaux, spssdata
alldata = spssdata.Spssdata(names=False).fetchall()
nvars = len(alldata[0])
ncases = len(alldata)
vnames = [spss.GetVariableName(i) for i in range(nvars)]
empty = set([''])
varsets = {}
for v in range(nvars):
varsets[v] = set([alldata[i][v].strip() for i in range(ncases)]).difference(empty)
rows = []
for v1 in range(nvars):
counts = []
for v2 in range(nvars):
counts.append(len(varsets[v1].intersection(varsets[v2])))
rows.append(counts)
spss.StartProcedure("ValuesInCommon")
table = spss.BasePivotTable("Values in Common", "COMMON")
table.SetDefaultFormatSpec(spss.FormatSpec.Count)
table.SimplePivotTable(rowdim = "Variable",
rowlabels=vnames,
coldim="Variables ",
collabels=vnames,
cells=rows)
spss.EndProcedure()
end program.