Archive for the ‘SPSS指令’ Category

如何绘制个人增长曲线图?

星期日, 四月 18th, 2010

Z @ 2010-04-15:

我们有一3个wave的panel样本,用GLM Repeated Measures分析数据,并从中画出三个时间点上样本的平均值。我们写了一篇论文投给某国际期刊,有位评审人要求我们随机抽取10人,在同一图里显示各自的growth curves。我们在SPSS中试了很久,怎么也无法制作这种图。不知是否可以在SPSS中“自动”做到?

庄主 @ 2010-04-18:

最近我教的统计课里,也有一位同学提出相同的问题,其答案在于纵向数据的特殊结构。一般说来,纵向数据的结构有“矮胖型”和“瘦长型”两种。但你们需要的是第三种结构。

矮胖型数据与更常见的横向数据相似,每一列是一个变量、每一行是一个个案,由于纵向数据的因变量有多个时点的观测值,每个观察值被当做一个变量,分别占领一列,一般在因变量名后加下标1、2、…、t(t=时间点个数)来显示各自的观测时间点。所以,这种结构的正式学名叫做“multivariate format”(因变量多列型)。如表一代表你们的数据,其中Y1、Y2和Y3是因变量Y在三个时间点上的观察值,注意它们是被当做三个变量分别各占据一列,X是自变量(只测量一次,所以只有一列)、最后的“…”表示还可以有其它自变量。GLM、SEM等都是使用这种结构的数据。但是,这种数据无法用来制作“intrapersonal growth curves”。

表一、因变量多列型数据结构(n行记录、t列因变量)

ID Y1 Y2 Y3 X ...
1 y11 y12 y13 x1
2 y21 y22 y23 x2
... ...
n yn1 yn2 yn3 xn

在瘦长型结构中,因变量只占一列,但是每个个案占三列,因此因变量y1、y2和y3分布在这三行之中(见表二)。为了保留Y的观测时间点,新增加了一个变量Time,取值1、2、…、t。这种结构的正式学名叫做“multirecord format”(个案多行型),是HLM和其他多层分析软件所要求的数据格式。在这种数据结构中,你可以通过选择个人的ID来显示一个人的增长曲线,但也无法在同一图中显示多人的增长曲线。

表二、个案多行型数据结构(n x t行记录、1列因变量)

ID Time Y X
1 1 y11 x1
1 2 y12 x1
1 3 y13 x1
2 1 y21 x2
2 2 y22 x2
2 3 y23 x2
n 1 yn1 xn
n 2 yn2 xn
n 3 yn3 xn

如要在同一图中显示多条增长曲线,需要将矮胖型或瘦长型数据转换成第三种结构,这在文献中还没有专门的名称,我姑且称之为individuals-as-variables format(“每人一列型”),如表三所示。这种结构更加“奇怪”,每一列是一个人的因变量或自变量,而每一行是一个时间点。本例t = 3,所以只有三行,比起矮胖型的n行来更加矮胖了。这种结构不适合做统计分析,但十分适合做各种图形,如可以做以Time为X-轴、单个或多个Y为Y-轴的增长曲线,也可以做以X为X-轴、Y为Y-轴的个人层面X-Y散点图。

表三、每人一列型数据结构(t行记录、n列因变量)

Time ID1_Y ID1_X ID2_Y ID2_X IDn_Y IDn_X
1 y11 x1 y21 x2 yn1 xn
2 y12 x1 y22 x2 yn2 xn
3 y13 x1 y23 x3 yn3 xn

好了,根据上述原理,你可以按需要而将数据在这三种结构之间互相转换。当然,如果你会使用SPSS的Syntax指令,确实可以用以下(或类似)的指令来“自动化”操作(注:指令中的大写字母是SPSS指令、小写字母是可以替代的变量名或文件名)。

*1. 假定你的数据是矮胖型结构,首先转换成瘦长数据.
VECTOR j=y1 to y3.
LOOP i=1 to 3.
COMPUTE y=j(i).
COMPUTE time=i.
XSAVE OUT 'r:\temp.sav'/KEEP id time y x.
END LOOP.
EXE.

*2. 随机抽取10个个案.
SAMPLE 10 FROM 100.  
EXE.
MATCH FILES FILE */KEEP id.    /*只保留被抽取的id.
AUTORECODE id/into newid.      /*对id重新排序.

*3. 与瘦长数据并行对接.
MATCH FILES TABLE */FILE 'r:\temp.sav'/BY id.
SELECT IF newid>0.     /*剔除没有newid的个案.
EXE.

*4. 从瘦长数据中逐个提取个案,分别保留到单独文件中.
DEFINE !newcase (!POS, !CMDEND).
!DO !i !IN (!1).
TEMP.
SELECT IF newid=!i.
SAVE OUT !QUOTE(!CONCAT('r:\newcase', !i, '.sav'))
  /KEEP time y x
  /rename (y=!concat('y', !i)/rename (x=!concat('x', !i).
!DOEND.
!ENDDEFINE.
!newcase 1 2 3 4 5 6 7 8 9 10.
EXE.

*5. 将10个单独文件平行对接起来,构成最后的“个案每列”结构.
MATCH FILES FILE 'r:\newcase1.sav'
  /FILE 'r:\newcase2.sav'
  /FILE 'r:\newcase3.sav'
  /FILE 'r:\newcase4.sav'
  /FILE 'r:\newcase5.sav'
  /FILE 'r:\newcase6.sav'
  /FILE 'r:\newcase7.sav'
  /FILE 'r:\newcase8.sav'
  /FILE 'r:\newcase9.sav'
  /FILE 'r:\newcase10.sav'.
EXE.

*6. 打印10个因变量对时间的散点图.
TSPLOT y1 y2 y3 y4 y5 y6 y7 y8 y9 y10/ID=time.

以下是步骤6制作的10条“个人增长曲线“图,估计就是你们要画的那种了。

image

如何在SPSS里删除重复ID的个案?

星期日, 八月 2nd, 2009

L @ 2009-08-01:

如果在SPSS数据库里有一个变量是对case的编号,现在有可能某些case 是重复出现的,我想要将重复出现的case只保留一个,其余重复则删除掉,怎么完成这个任务?(除了手动的以外。)

庄主 @ 2009-08-02:

SPSS13版或之后的Data菜单下有一个“Identifying Duplicate Cases”的程序,应该可以解决你的问题。但我没有用过那个程序,而是用下述的syntax写一个程序来做,自己写的程序放心一点,不会错杀无辜的个案。(注:以下syntax其中的“ROW”和“ROW2”是两个临时变量,事后可以删去。如果你case的编号变量名不叫“ID”,请修改ID。)

sort cases by ID.
compute ROW=$casenum.
aggregate outfile 'c:\temp.sav'/break ID/ROW2=first(ROW).
match files file */table 'c:\temp.sav'/by ID.
select if ROW=ROW2.
delete variable ROW ROW2.
exe.

强烈建议你运行前,请先用下述模拟数据试一下,以检验上述程序是否对(即没有放过任何需要删的个案、也没有错删任何需要保留的个案)。

input program.
loop #i=1 to 10.
loop #j=1 to 3.
compute ID=#i.
end case.
end loop.
end loop.
end file.
end input program.
sort cases by ID.
compute ROW=$casenum.
aggregate outfile 'c:\temp.sav'/break ID/ROW2=first(ROW).
match files file */table 'c:\temp.sav'/by ID.
select if ROW=ROW2.
delete variable ROW ROW2.
exe.

数据a 数据b 数据c 数据d
image image image image

上述syntax的第1-11句生成一个含有两个变量(ID和ROW)、30个个案(其中仅10个独立个案,但每个个案重复3次)的数据(见下图数据a)。第12句将数据a中每三个重复个案中的第一条记录的ID和行序号ROW抽出来保存到临时文件temp.sav中(见数据b)。第13句将数据a和数据b合并成数据c。第14句将数据c中的ROW(即数据a中的行序号)与ROW2(即数据b中的每个个案第一行的行序号)相等者选出;也就是说,将ROW和ROW2不相等者(即每个个案的重复行)删除。最后,第15句将临时变量ROW和ROW2删除,结果就是你想要的数据d。