Date: Tue, 20 Sep 2005 12:23:47 +0200
Reply-To: Marta García-Granero
<biostatistics@terra.es>
Sender: "SPSSX(r) Discussion" <SPSSX-L@LISTSERV.UGA.EDU>
From: Marta García-Granero
<biostatistics@terra.es>
Organization: Asesoría Bioestadística
Subject: Re: Transforming vector data into matrix format
In-Reply-To: <59094EC2301DBB47B2F3671ACCA99ED9027B264D@TOLEXCH01.nfor.com>
Content-Type: text/plain; charset=ISO-8859-15
Hi Paul,
Back again with a slightly modified (faster) version of the code I
posted previously (waiting for the traffic lights to turn green gives
plenty of time to think of MATRIX code - yes, I know I'm a bit freaky
and I should seek medical assistance, I just can't help it).
My first version computed upper & lower diagonal elements in 2
different data passes. This makes the code easier to understand, but
slower than necessary. This is an improved version, tested with 4 rows
of data (the ones you gave), and with a simulated dataset with 1000
cases (the MATRIX code took around 4 seconds in a PII-400 Mhz with 256
Mb RAM, W2000 & SPSS 12). For this last run, MXLOOPS had to be
increased.
Cheers, Marta
**********************************************************************
* (Q) I have a data set of 10 variables where each vector represents
* the ranking of those concepts by one individual. To be specific
* the data looks like this:
*
* ID v1 v2 v3 v4 v5 v6 v7 v8 v9 v10
* 1 2 3 7 8 10 1 4 5 6 9
* 2 10 2 1 3 4 5 6 7 9 8
* 3 9 6 4 2 1 3 5 7 10 8
* . . . . . . . . . . .
* . . . . . . . . . . .
* . . . . . . . . . . .
* . . . . . . . . . . .
* 1000 2 4 8 10 9 3 5 7 1 6
*
* I want to change this data into a matrix where everything in columns
* above the diagonal is the number of times each concept was ranked higher
* than the corresponding row concept and everything in columns below the
* diagonal is the number of times each concept was ranked lower than the
* row concept. The diagonals themselves will be equal to N/2.
* (A) Using the presented part of the dataset (only 4 rows) *.
DATA LIST LIST/id v1 TO v10 (11 F8.0).
BEGIN DATA
1 2 3 7 8 10 1 4 5 6 9
2 10 2 1 3 4 5 6 7 9 8
3 9 6 4 2 1 3 5 7 10 8
1000 2 4 8 10 9 3 5 7 1 6
END DATA.
MATRIX.
GET data /VAR=v1 TO v10 /NAMES=vnames.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
COMPUTE diagmat=MAKE(nvars,nvars,0).
* Set diagonal values to n/2 *.
CALL SETDIAG(diagmat,ndata/2).
* Upper & lower diagonal elements in one data pass *.
LOOP i=1 TO ndata.
- LOOP j=1 TO nvars-1.
- LOOP k=j TO nvars.
- DO IF data(i,j) GT data(i,k). /* Upper *.
- COMPUTE diagmat(j,k)=diagmat(j,k)+1.
- ELSE IF data(i,j) LT data(i,k). /* Lower *.
- COMPUTE diagmat(k,j)=diagmat(k,j)+1.
- END IF.
- END LOOP.
- END LOOP.
END LOOP.
* Report *.
PRINT diagmat
/TITLE='Matrix output:'
/CNAMES=vnames
/RNAMES=vnames.
* Save matrix to file *.
SAVE diagmat /OUTFILE='c:\temp\MATRIX.sav' /NAMES=vnames.
END MATRIX.
GET FILE='C:\Temp\MATRIX.sav'.
FORMAT v1 TO v10 (F8.0).
LIST.
**********************************************************
* Testing with a bigger dataset (fake data) *.
INPUT PROGRAM.
- VECTOR x(1000).
- LOOP #I = 1 TO 10.
- LOOP #J = 1 TO 1000.
- COMPUTE x(#J) = NORMAL(1).
- END LOOP.
- END CASE.
- END LOOP.
- END FILE.
END INPUT PROGRAM.
EXEC.
PRESERVE.
SET ERRORS=NONE RESULTS=NONE. /* Output is shut-down *.
RANK VARIABLES=x1 TO x1000(A) /RANK /PRINT=NO
/TIES=CONDENSE .
MATCH FILES FILE=*
/DROP=x1 TO x1000.
FLIP.
RESTORE.
RENAME VARIABLES (var001 TO var010 = v1 TO v10).
FORMAT v1 TO v10 (F8.0).
* Now the false data are ready (10 variables & 1000 cases) *.
PRESERVE.
SET MXLOOPS=1000. /* At least equal to number of cases in dataset *.
SHOW MXLOOPS.
MATRIX.
GET data /VAR=v1 TO v10 /NAMES=vnames.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
COMPUTE diagmat=MAKE(nvars,nvars,0).
* Set diagonal values to n/2 *.
CALL SETDIAG(diagmat,ndata/2).
* Upper & lower diagonal elements in one data pass *.
LOOP i=1 TO ndata.
- LOOP j=1 TO nvars-1.
- LOOP k=j TO nvars.
- DO IF data(i,j) GT data(i,k). /* Upper *.
- COMPUTE diagmat(j,k)=diagmat(j,k)+1.
- ELSE IF data(i,j) LT data(i,k). /* Lower *.
- COMPUTE diagmat(k,j)=diagmat(k,j)+1.
- END IF.
- END LOOP.
- END LOOP.
END LOOP.
* Report *.
PRINT diagmat
/TITLE='Matrix output:'
/CNAMES=vnames
/RNAMES=vnames.
* Save matrix to file *.
SAVE diagmat /OUTFILE='c:\temp\MATRIX.sav' /NAMES=vnames.
END MATRIX.
RESTORE.
SHOW MXLOOPS.
GET FILE='C:\Temp\MATRIX.sav'.
FORMAT v1 TO v10 (F8.0).
LIST.