insert new cases - conditional

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

insert new cases - conditional

Jodene Fine
Dear SPSS Guys and Gals,

My head is hurting. Here is my problem. I need to conditionally add 2
cases above a flagged case. For example:

*-------------------------------------.
data list free / caseno v1 v2 flag
begin data
1 0 0 0
2 0 0 0
3 0 0 1
4 0 0 0
end data.

* I need to add 2 cases between caseno 2 and 3.
* (note flag is with caseno 3).
* The resulting file should look like this.

begin data /casno v1 v2 flag
1 0 0 0
2 0 0 0
0 0 0 0
0 0 0 0
3 0 0 1
4 0 0 0
end data.

*----------------------------.

I presume we will need to sort backwards by caseno, and use LAG, but I'm
flumoxed as to how to add the cases into the file.

Better brains than mine will figure this out, no doubt.

Thank you for your time and attention, and happy spring to everybody.

Jodene

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: insert new cases - conditional

Marta Garcia-Granero
Hi Jodene

I know that there is a solution using XSAVE, but I like to use MATRIX
for data handling.

* Your data *.
DATA LIST LIST/ caseno v1 v2 flag (4 F8).
BEGIN DATA
1 0 0 0
2 0 0 0
3 0 0 1
4 0 0 0
END DATA.

MATRIX.
GET data /VAR=ALL /NAMES=vnames.
* Find out dataset size and number of variables *.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
* Create an insert with 2 rows and the number of variables *.
COMPUTE insert=MAKE(2,nvars,0).
* Locate row with "flag=1" - code assumes the flag variable is the last *.
LOOP location = 1 TO ndata.
- DO IF (data(location,nvars) = 1).
- BREAK.
- END IF.
END LOOP.
* Split data in two according to "flag=1" location *.
COMPUTE newdata1=data(1:(location-1),:).
COMPUTE newdata2=data(location:ndata,:).
* Add inserted rows in correct position *.
COMPUTE newdata={newdata1;insert;newdata2}.
* Replace original data by the new ones *.
SAVE newdata /OUTFILE=* /NAMES=vnames.
END MATRIX.

LIST.

You will get other solutions that might be easier,but this one was the
fastest reply ;)

Best regards,
Marta García-Granero

> Dear SPSS Guys and Gals,
>
> My head is hurting. Here is my problem. I need to conditionally add 2
> cases above a flagged case. For example:
>
> *-------------------------------------.
> data list free / caseno v1 v2 flag
> begin data
> 1 0 0 0
> 2 0 0 0
> 3 0 0 1
> 4 0 0 0
> end data.
>
> * I need to add 2 cases between caseno 2 and 3.
> * (note flag is with caseno 3).
> * The resulting file should look like this.
>
> begin data /casno v1 v2 flag
> 1 0 0 0
> 2 0 0 0
> 0 0 0 0
> 0 0 0 0
> 3 0 0 1
> 4 0 0 0
> end data.
>
> *----------------------------.
>
> I presume we will need to sort backwards by caseno, and use LAG, but I'm
> flumoxed as to how to add the cases into the file.
>
> Better brains than mine will figure this out, no doubt.
>
> Thank you for your time and attention, and happy spring to everybody.
>
> Jodene
>
> =====================
> To manage your subscription to SPSSX-L, send a message to
> [hidden email] (not to SPSSX-L), with no body text except the
> command. To leave the list, send the command
> SIGNOFF SPSSX-L
> For a list of commands to manage subscriptions, send the command
> INFO REFCARD
>
>

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: insert new cases - conditional

Jodene Fine
Many thanks to Marta, who offered an elegant, compact solution to the
problem I posed.

Marta's code requires that there is only one instance of case insertion, but
in reality, I will have many cases where this instance occurs. Thus, the
blame lies with the question-asker. I have tried to fix the matrix code to
perform this action repeatedly, using loops and setting the flag to -1 if
that line has been done. Unfortunately, I've been unable to successfully
implement code that doesn't blow up.

May I please ask for further comment, given the following input data?

Thank you all.
Jodene

* Your data *.
DATA LIST LIST/ caseno v1 v2 flag (4 F8).
BEGIN DATA
1 0 0 0
2 0 0 0
3 0 0 1
4 0 0 0
5 0 0 1
6 0 0 0
7 0 0 0
8 0 0 0
9 0 0 1
10 0 0 0
END DATA.

-----Original Message-----
From: SPSSX(r) Discussion [mailto:[hidden email]] On Behalf Of
Marta García-Granero
Sent: Tuesday, May 06, 2008 4:04 AM
To: [hidden email]
Subject: Re: insert new cases - conditional

Hi Jodene

I know that there is a solution using XSAVE, but I like to use MATRIX
for data handling.

* Your data *.
DATA LIST LIST/ caseno v1 v2 flag (4 F8).
BEGIN DATA
1 0 0 0
2 0 0 0
3 0 0 1
4 0 0 0
END DATA.

MATRIX.
GET data /VAR=ALL /NAMES=vnames.
* Find out dataset size and number of variables *.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
* Create an insert with 2 rows and the number of variables *.
COMPUTE insert=MAKE(2,nvars,0).
* Locate row with "flag=1" - code assumes the flag variable is the last *.
LOOP location = 1 TO ndata.
- DO IF (data(location,nvars) = 1).
- BREAK.
- END IF.
END LOOP.
* Split data in two according to "flag=1" location *.
COMPUTE newdata1=data(1:(location-1),:).
COMPUTE newdata2=data(location:ndata,:).
* Add inserted rows in correct position *.
COMPUTE newdata={newdata1;insert;newdata2}.
* Replace original data by the new ones *.
SAVE newdata /OUTFILE=* /NAMES=vnames.
END MATRIX.

LIST.

You will get other solutions that might be easier,but this one was the
fastest reply ;)

Best regards,
Marta García-Granero

> Dear SPSS Guys and Gals,
>
> My head is hurting. Here is my problem. I need to conditionally add 2
> cases above a flagged case. For example:
>
> *-------------------------------------.
> data list free / caseno v1 v2 flag
> begin data
> 1 0 0 0
> 2 0 0 0
> 3 0 0 1
> 4 0 0 0
> end data.
>
> * I need to add 2 cases between caseno 2 and 3.
> * (note flag is with caseno 3).
> * The resulting file should look like this.
>
> begin data /casno v1 v2 flag
> 1 0 0 0
> 2 0 0 0
> 0 0 0 0
> 0 0 0 0
> 3 0 0 1
> 4 0 0 0
> end data.
>
> *----------------------------.
>
> I presume we will need to sort backwards by caseno, and use LAG, but I'm
> flumoxed as to how to add the cases into the file.
>
> Better brains than mine will figure this out, no doubt.
>
> Thank you for your time and attention, and happy spring to everybody.
>
> Jodene
>
> =====================
> To manage your subscription to SPSSX-L, send a message to
> [hidden email] (not to SPSSX-L), with no body text except the
> command. To leave the list, send the command
> SIGNOFF SPSSX-L
> For a list of commands to manage subscriptions, send the command
> INFO REFCARD
>
>

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: insert new cases - conditional

Marta Garcia-Granero
Jodene Fine escribió:

> Many thanks to Marta, who offered an elegant, compact solution to the
> problem I posed.
>
> Marta's code requires that there is only one instance of case insertion, but
> in reality, I will have many cases where this instance occurs. Thus, the
> blame lies with the question-asker. I have tried to fix the matrix code to
> perform this action repeatedly, using loops and setting the flag to -1 if
> that line has been done. Unfortunately, I've been unable to successfully
> implement code that doesn't blow up.
>
I half expected it, therefore I had though of it and here is the
solution. Just to get preparedt o other exceptions.the code will need
further modification if:

- you have missing data scattered in the dataset
- you have string or date variables among the numeric ones.

* your new data *.
DATA LIST LIST/ caseno v1 v2 flag (4 F8).
BEGIN DATA
 1 0 0 0
 2 0 0 0
 3 0 0 1
 4 0 0 0
 5 0 0 1
 6 0 0 0
 7 0 0 0
 8 0 0 0
 9 0 0 1
10 0 0 0
END DATA.

MATRIX.
GET data /VAR=ALL /NAMES=vnames.
* Find out dataset size and number of variables *.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
* Find out the number of "flag=1" present *.
COMPUTE nflags=CSUM(data(:,nvars)).
* Create an insert with 2 rows and the number of variables *.
COMPUTE insert=MAKE(2,nvars,0).
* Outer loop (runs as many times as flag=1) *.
COMPUTE loc=1.
LOOP times = 1 TO nflags.
* Locate row with "flag=1" - code assumes the flag variable is the last *.
LOOP location = loc TO ndata.
- DO IF (data(location,nvars) = 1).
- BREAK.
- END IF.
END LOOP.
* Split data in two according to "flag=1" location *.
COMPUTE newdata1=data(1:(location-1),:).
COMPUTE newdata2=data(location:ndata,:).
* Add inserted rows in correct position *.
COMPUTE data={newdata1;insert;newdata2}.
* Shifts the loop start to 1st position after located flag *.
COMPUTE loc=location+3.
* Since there are two more rows, we must increase "ndata" *.
COMPUTE ndata=NROW(data).
* Ends outer loop *.
END LOOP.
* Replace original data by the new ones *.
SAVE data /OUTFILE=* /NAMES=vnames.
END MATRIX.

FORMAT ALL (F8).
LIST.

Best regards,
Marta

(BTW, cute word "flummox", I didn't know it and had to consult it in my
Webster's Dictionary)

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD
Reply | Threaded
Open this post in threaded view
|

Re: insert new cases - conditional

Peck, Jon
If you have SPSS 16 and have installed Python programmability, here is a simple solution using the new, very powerful Dataset class.  It assumes that the dataset is open, and the flag variable is last.

BEGIN PROGRAM.
import spss
spss.StartDataStep()
ds = spss.Dataset()
cases = ds.cases
count = spss.GetCaseCount()
for i in xrange(count-1,-1,-1):
    if cases[i][-1] == 1:
        cases.insert([], i)
        cases.insert([], i)
spss.EndDataStep()
END PROGRAM.

This walks backwards through the dataset, and each time the last variable in the case is 1, it inserts two empty cases in front of it.

HTH,
Jon Peck

-----Original Message-----
From: SPSSX(r) Discussion [mailto:[hidden email]] On Behalf Of Marta García-Granero
Sent: Tuesday, May 06, 2008 9:40 AM
To: [hidden email]
Subject: Re: [SPSSX-L] insert new cases - conditional

Jodene Fine escribió:

> Many thanks to Marta, who offered an elegant, compact solution to the
> problem I posed.
>
> Marta's code requires that there is only one instance of case insertion, but
> in reality, I will have many cases where this instance occurs. Thus, the
> blame lies with the question-asker. I have tried to fix the matrix code to
> perform this action repeatedly, using loops and setting the flag to -1 if
> that line has been done. Unfortunately, I've been unable to successfully
> implement code that doesn't blow up.
>
I half expected it, therefore I had though of it and here is the
solution. Just to get preparedt o other exceptions.the code will need
further modification if:

- you have missing data scattered in the dataset
- you have string or date variables among the numeric ones.

* your new data *.
DATA LIST LIST/ caseno v1 v2 flag (4 F8).
BEGIN DATA
 1 0 0 0
 2 0 0 0
 3 0 0 1
 4 0 0 0
 5 0 0 1
 6 0 0 0
 7 0 0 0
 8 0 0 0
 9 0 0 1
10 0 0 0
END DATA.

MATRIX.
GET data /VAR=ALL /NAMES=vnames.
* Find out dataset size and number of variables *.
COMPUTE nvars=NCOL(data).
COMPUTE ndata=NROW(data).
* Find out the number of "flag=1" present *.
COMPUTE nflags=CSUM(data(:,nvars)).
* Create an insert with 2 rows and the number of variables *.
COMPUTE insert=MAKE(2,nvars,0).
* Outer loop (runs as many times as flag=1) *.
COMPUTE loc=1.
LOOP times = 1 TO nflags.
* Locate row with "flag=1" - code assumes the flag variable is the last *.
LOOP location = loc TO ndata.
- DO IF (data(location,nvars) = 1).
- BREAK.
- END IF.
END LOOP.
* Split data in two according to "flag=1" location *.
COMPUTE newdata1=data(1:(location-1),:).
COMPUTE newdata2=data(location:ndata,:).
* Add inserted rows in correct position *.
COMPUTE data={newdata1;insert;newdata2}.
* Shifts the loop start to 1st position after located flag *.
COMPUTE loc=location+3.
* Since there are two more rows, we must increase "ndata" *.
COMPUTE ndata=NROW(data).
* Ends outer loop *.
END LOOP.
* Replace original data by the new ones *.
SAVE data /OUTFILE=* /NAMES=vnames.
END MATRIX.

FORMAT ALL (F8).
LIST.

Best regards,
Marta

(BTW, cute word "flummox", I didn't know it and had to consult it in my
Webster's Dictionary)

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD

=====================
To manage your subscription to SPSSX-L, send a message to
[hidden email] (not to SPSSX-L), with no body text except the
command. To leave the list, send the command
SIGNOFF SPSSX-L
For a list of commands to manage subscriptions, send the command
INFO REFCARD