Emergency Help!- Maybe Loops and Vectors

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

Emergency Help!- Maybe Loops and Vectors

Zachary Feinstein
I have 60 fields with the numbers 1 - 15 in them across the fields.  So, for the first record the numbers might be 11, 8, 2, 9 and not adjacent to each other.
 
These numbers can also repeat each other.  Another example could be the numbers 1, 10, 11, 11, 15, 17, 2.
 
I need to fill in four blank fields with the first four cases that I find without doing any repeats.  I was thinking of doing it via VECTORS and LOOPS but my code will just not work.
 
Also- there will be times when I might not have 4 numbers to fill in/left-pad.  Maybe I would have some instances of when there just 2.
 
I was thinking of doing a LOOP of one within the other (using i & j, etc. for the 60 fields and the 4). but the same last value is filled in for all of my four fields and it is always the last one.
 
I am sorry about stating this is an emergency but I really am trying my best to make this work and work quickly.  I have been trying different things all day and am very frustrated a this needs to be done by tomorrow.
 
Thank you and feel free to call or e-mail me if that would help.  I will be super-grateful.
 
Zachary
(651) 698-2184
 

Reply | Threaded
Open this post in threaded view
|

Re: Emergency Help!- Maybe Loops and Vectors

Allan Lundy, PhD

Zachary,
If no-one comes up with a more elegant solution, something like this might work. 

I am assuming that you use the word "cases" below to mean "instances" rather than "subjects."

Let's say your 60 fields are V1 thru V60.

In a general sense I suspect that your problem is that you are trying to work from V1 to V60 instead of the other way around.

if (~sysmis(V60)) compute first=V60.
if (~sysmis(V59)) compute first=V59.
if (~sysmis(V58)) compute first=V58.
  :
if (~sysmis(V1)) compute first=V1.

if (~(sysmis(V60) | (V60=first)) ) compute second=V60.
if (~(sysmis(V59) | (V59=first)) ) compute second=V59.
if (~(sysmis(V58) | (V58=first)) ) compute second=V58.
  :
if (~(sysmis(V1) | (V1=first)) ) compute second=V1.

For variable third, you would use:    if (~(sysmis(V1) | (V1=first) | (V1=second)) )  and for variable forth you would add a check for (V1=third).

Of course it should be possible to nest the statements so you don't have 60 x 4 = 240 statements, but this should get the idea across.

Good luck!


At 06:39 PM 6/4/2009, Zachary Feinstein wrote:
I have 60 fields with the numbers 1 - 15 in them across the fields.  So, for the first record the numbers might be 11, 8, 2, 9 and not adjacent to each other.
 
These numbers can also repeat each other.  Another example could be the numbers 1, 10, 11, 11, 15, 17, 2.
 
I need to fill in four blank fields with the first four cases that I find without doing any repeats.  I was thinking of doing it via VECTORS and LOOPS but my code will just not work.
 
Also- there will be times when I might not have 4 numbers to fill in/left-pad.  Maybe I would have some instances of when there just 2.
 
I was thinking of doing a LOOP of one within the other (using i & j, etc. for the 60 fields and the 4). but the same last value is filled in for all of my four fields and it is always the last one.
 
I am sorry about stating this is an emergency but I really am trying my best to make this work and work quickly.  I have been trying different things all day and am very frustrated a this needs to be done by tomorrow.
 
Thank you and feel free to call or e-mail me if that would help.  I will be super-grateful.
 
Zachary
[hidden email]
(651) 698-2184
 

Allan Lundy, PhD
Research Consultant      [hidden email]

Business & Cell (any time): 215 820-8100   
Home: Voice and fax (8am - 10pm,  7 days/week):  215 885-5313
Address:  108 Cliff Terrace,  Wyncote, PA 19095
Visit my Web site at   www.dissertationconsulting.net
===================== 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: Emergency Help!- Maybe Loops and Vectors

Richard Ristow
In reply to this post by Zachary Feinstein
At 06:39 PM 6/4/2009, Zachary Feinstein wrote:

I have 60 fields with the numbers 1 - 15 in them across the fields.  For example, the numbers might be 11, 8, 2, 9 and not adjacent to each other. The numbers can also repeat, for example numbers 1, 10, 11, 11, 15, 17, 2.
 
I need to fill in four blank fields with the first four [numbers] that I find without doing any repeats.  I was thinking of doing it via VECTORS and LOOPS but my code will just not work.
 
I was thinking of doing a LOOP of one within the other (using i & j, etc. for the 60 fields and the 4).

It is two-LOOP logic, but interleaved loop (the two loops running together), rather than nested. For interleaved loops, you need one LOOP statement, not two.

Interleaved loops are tricky to write, as I say having had trouble even though I've done this often. But, here's an example that selects 4 from 12, I think according to your rules.

The listing does not precisely match the code that's below. If was produced the code below, exactly, but I've deleted a lot of trace code and trace output from the listing, before posting.

Test data:
|-----------------------------|---------------------------|
|Output Created               |05-JUN-2009 00:55:10       |
|-----------------------------|---------------------------|
CaseID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12

  01    .  5  .  .  5  .  7  5 10   .   8   9
  02    .  5  .  7  .  .  9  6  9   .   .   .
  03    4 10  .  .  4  6  5  .  3   7   8   3
  04    7  .  .  .  5  . 10  7  3   4   5   4
  05    .  .  3  5  .  .  5  .  .   4   .   6
  06    5  .  6  .  9  4  .  3  .   .   5   8
  07    .  3  9  9 . 10  7  4  8   9   .   6
  08    9  5  .  3  7  6  .  4  .   .   .   .
  09    .  5  6  .  5  6  3  .  3   7   9   .
  10    3  5  4  5  6  .  7  9  7   8   .   .

Number of cases read:  10    Number of cases listed:  10

 
STRING    SPCE  (A4).

NUMERIC       TGT1 TO TGT4 (F2).
VECTOR    T = TGT1 TO TGT4.
VECTOR    V = V1   TO V12.

COMPUTE #Destination = 0.

LOOP    #Source = 1 TO 12.
.  DO IF   NOT MISSING(V(#Source)).
*     We have a number. Have we seen it before? .
.     COMPUTE  #Match = 0.
.     DO IF    #Destination GT 0.
.      LOOP    #FoundOnes = 1 to #Destination.
.        IF  T(#Foundones) EQ V(#Source)
                 #Match =  1.
.      END LOOP
              IF #Match GT 0.
.     END IF.
*     We have a number, we know whether it      .
*     matches anything found earlier; if it ,   .
*     doesn't, store it.                        .
.     DO IF   NOT(#Match) & #Destination LT 4.
.        COMPUTE  #Destination  =#Destination +1.
.        COMPUTE T(#Destination)= V(#Source).
.     END IF.

.  END IF /* of the test for non-missing source*/.
END LOOP.

LIST.

List
|-----------------------------|---------------------------|
|Output Created               |05-JUN-2009 00:55:11       |
|-----------------------------|---------------------------|
CaseID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 SPCE TGT1 TGT2 TGT3 TGT4

  01    .  5  .  .  5  .  7  5 10   .   8   9        5    7   10    8
  02    .  5  .  7  .  .  9  6  9   .   .   .        5    7    9    6
  03    4 10  .  .  4  6  5  .  3   7   8   3        4   10    6    5
  04    7  .  .  .  5  . 10  7  3   4   5   4        7    5   10    3
  05    .  .  3  5  .  .  5  .  .   4   .   6        3    5    4    6
  06    5  .  6  .  9  4  .  3  .   .   5   8        5    6    9    4
  07    .  3  9  9 . 10  7  4  8   9   .   6        3    9   10    7
  08    9  5  .  3  7  6  .  4  .   .   .   .        9    5    3    7
  09    .  5  6  .  5  6  3  .  3   7   9   .        5    6    3    7
  10    3  5  4  5  6  .  7  9  7   8   .   .        3    5    4    6

Number of cases read:  10    Number of cases listed:  10
=============================
APPENDIX: Test data, and code
=============================
*  ...............     Test data            .................... .
SET RNG    =MT   /* 'Mersenne twister' random number generator*/ .
SET MTINDEX=1329 /*  Providence, RI telephone book            */ .

NEW FILE.

INPUT PROGRAM.
.  NUMERIC CaseID (N2).
.  LEAVE   CaseID.
.  VECTOR  V(12,F2).

.  LOOP   CaseID = 1 TO 10.
.     LOOP #Idx  = 1 TO 12.
.        IF RV.BERNOULLI(0.6) 
            V(#Idx) = TRUNC(RV.UNIFORM(3,11)).
.     END  LOOP.
.     END CASE.
.  END LOOP.

END FILE.
END INPUT PROGRAM.

*  ................   Post after this point   .................. .
*  ............................................................. .
LIST.

STRING    SPCE  (A4).

NUMERIC       TGT1 TO TGT4 (F2).
VECTOR    T = TGT1 TO TGT4.
VECTOR    V = V1   TO V12.

COMPUTE #Destination = 0.

LOOP    #Source = 1 TO 12.
.  DO IF   NOT MISSING(V(#Source)).
*     We have a number. Have we seen it before? .
.     COMPUTE  #Match = 0.
.     DO IF    #Destination GT 0.
.      LOOP    #FoundOnes = 1 to #Destination.
.        IF  T(#Foundones) EQ V(#Source)
                 #Match =  1.
.      END LOOP
              IF #Match GT 0.
.     END IF.
*     We have a number, we know whether it      .
*     matches anything found earlier; if it ,   .
*     doesn't, store it.                        .
.     DO IF   NOT(#Match) & #Destination LT 4.
.        COMPUTE  #Destination  =#Destination +1.
.        COMPUTE T(#Destination)= V(#Source).
.     END IF.

*      The following produces a good deal of trace code:  .
.      FORMATS #Destination    #Source    #Match (F2).
.      NUMERIC #ValDest   #ValSrce               (F2).
. /**/ COMPUTE #ValDest = T(#Destination).
. /**/ COMPUTE #ValSrce = V(#Source).
. /**/ PRINT  / 'Idx: ' #Destination #Source         /*-*/.
. /**/ PRINT  / 'Val: ' #ValDest     #ValSrce #MATCH /*-*/.

.  END IF /* of the test for non-missing source*/.
END LOOP.

LIST.
LIST.

===================== 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