add cases to a repeating table based on previous values

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

add cases to a repeating table based on previous values

wsu_wright
I have a dataset reporting the start year, person rank and end year and
need to create a repeating table by ID that fills in the intervening
years carrying the rank forward until it changes.  I've used loops & do
repeats before but never to add records so I'm not sure what is the best
method.  I have listed below the original and requested data.  Thanks in
advance.


Original data structure:

ID, startFY, rank, endFY

1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980


new data structure needed:

1 2003 4 2003
2 1985 5 1991
2 1986 5 1991
2 1987 2 1991
2 1988 2 1991
2 1989 2 1991
2 1990 1 1991
2 1991 1 1991
3 1979 4 1980
3 1980 4 1980

=====================
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: add cases to a repeating table based on previous values

Bruce Weaver
Administrator
I expect there's some more elegant method, but it is late on a Friday afternoon!

new file.
dataset close all.
data list list / ID startFY rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.

* I will need flags for First and Last records within an ID.

match files
 file = * / by ID /
 FIRST = FirstRec / LAST = LastRec.
exe.

* Sort cases in reverse order so I can use LAG.

compute case = $casenum.
formats case (f5.0).
exe.
sort cases by case(d).

******************* .
if LastRec final = endFY.
if NOT LastRec final = lag(startFY) - 1.
formats final(f4.0).
******************* .

* Revert to original case order.

sort cases by case.

loop start = startFY to final.
xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
end loop.
execute.
get file = "C:\Temp\junk.sav".
formats start(f4.0).
list.

OUTPUT:

ID start  rank endFY
 
    1  2003     4  2003
    2  1985     5  1991
    2  1986     5  1991
    2  1987     2  1991
    2  1988     2  1991
    2  1989     2  1991
    2  1990     1  1991
    2  1991     1  1991
    3  1979     4  1980
    3  1980     4  1980
 
Number of cases read:  10    Number of cases listed:  10



David Wright-6 wrote
I have a dataset reporting the start year, person rank and end year and
need to create a repeating table by ID that fills in the intervening
years carrying the rank forward until it changes.  I've used loops & do
repeats before but never to add records so I'm not sure what is the best
method.  I have listed below the original and requested data.  Thanks in
advance.


Original data structure:

ID, startFY, rank, endFY

1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980


new data structure needed:

1 2003 4 2003
2 1985 5 1991
2 1986 5 1991
2 1987 2 1991
2 1988 2 1991
2 1989 2 1991
2 1990 1 1991
2 1991 1 1991
3 1979 4 1980
3 1980 4 1980

=====================
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
--
Bruce Weaver
bweaver@lakeheadu.ca
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

PLEASE NOTE THE FOLLOWING: 
1. My Hotmail account is not monitored regularly. To send me an e-mail, please use the address shown above.
2. The SPSSX Discussion forum on Nabble is no longer linked to the SPSSX-L listserv administered by UGA (https://listserv.uga.edu/).
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
This is similar with downside of requiring knowledge of max number of records.  Doesn't require sorts etc.
--
data list list / ID startFY rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.
CASESTOVARS  /ID=ID /GROUPBY=VARIABLE.
VECTOR starts=startfy.1 TO startfy.3 /ranks =rank.1 to rank.3 .
compute #done=0.
loop #=2 to 3.
+  compute rank=ranks(#-1).
+  DO IF NOT(MISSING(starts(#))).
+    compute #end= starts(#).
+  ELSE.
+    compute #end=endfy.
+    compute #done=1.
+  END IF.
+  loop startfy=starts(#-1) TO endfy .
+    XSAVE OUTFILE 'C:\Users\David\TEMP\long.sav' / KEEP ID startfy rank endfy.
+  end loop.
end loop If #done.
EXE.
GET FILE 'C:\Users\David\TEMP\long.sav' .
Bruce Weaver wrote
I expect there's some more elegant method, but it is late on a Friday afternoon!

new file.
dataset close all.
data list list / ID startFY rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.

* I will need flags for First and Last records within an ID.

match files
 file = * / by ID /
 FIRST = FirstRec / LAST = LastRec.
exe.

* Sort cases in reverse order so I can use LAG.

compute case = $casenum.
formats case (f5.0).
exe.
sort cases by case(d).

******************* .
if LastRec final = endFY.
if NOT LastRec final = lag(startFY) - 1.
formats final(f4.0).
******************* .

* Revert to original case order.

sort cases by case.

loop start = startFY to final.
xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
end loop.
execute.
get file = "C:\Temp\junk.sav".
formats start(f4.0).
list.

OUTPUT:

ID start  rank endFY
 
    1  2003     4  2003
    2  1985     5  1991
    2  1986     5  1991
    2  1987     2  1991
    2  1988     2  1991
    2  1989     2  1991
    2  1990     1  1991
    2  1991     1  1991
    3  1979     4  1980
    3  1980     4  1980
 
Number of cases read:  10    Number of cases listed:  10



David Wright-6 wrote
I have a dataset reporting the start year, person rank and end year and
need to create a repeating table by ID that fills in the intervening
years carrying the rank forward until it changes.  I've used loops & do
repeats before but never to add records so I'm not sure what is the best
method.  I have listed below the original and requested data.  Thanks in
advance.


Original data structure:

ID, startFY, rank, endFY

1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980


new data structure needed:

1 2003 4 2003
2 1985 5 1991
2 1986 5 1991
2 1987 2 1991
2 1988 2 1991
2 1989 2 1991
2 1990 1 1991
2 1991 1 1991
3 1979 4 1980
3 1980 4 1980

=====================
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
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

wsu_wright
In reply to this post by wsu_wright
Bruce/David,

Thanks for the quick reply.  Very interesting, two very different
approaches.  I follow the code up until the embedded xsave within the
loop, can you explain what is happening as it works through the loop
regarding the xsave.  Again, many thanks fellows, its always nice to
know that we have a community to fall back on when needing help.

Bruce-- your code worked in creating the new table structure.  David,
may have to tweak your code, it appears to be adding additional years
and not catching all the ranks.  I've listed below Bruce & David's
output file:

Original:
ID, sFY, rank, eFY
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980

Bruce's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    1       1991
2       1991    1       1991
3       1979    4       1980
3       1980    4       1980

David's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    5       1991
2       1988    5       1991
2       1989    5       1991
2       1990    5       1991
2       1991    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    2       1991
2       1991    2       1991
3       1979    4       1980
3       1980    4       1980


On Fri, Oct 19, 2012 at 5:17 PM, David Marso wrote:

> This is similar with downside of requiring knowledge of max number of
> records.  Doesn't require sorts etc.
> --
> data list list / ID startFY rank endFY (4f5.0).
> begin data
> 1 2003 4 2003
> 2 1985 5 1991
> 2 1987 2 1991
> 2 1990 1 1991
> 3 1979 4 1980
> end data.
> CASESTOVARS  /ID=ID /GROUPBY=VARIABLE.
> VECTOR starts=startfy.1 TO startfy.3 /ranks =rank.1 to rank.3 .
> compute #done=0.
> loop #=2 to 3.
> +  compute rank=ranks(#-1).
> +  DO IF NOT(MISSING(starts(#))).
> +    compute #end= starts(#).
> +  ELSE.
> +    compute #end=endfy.
> +    compute #done=1.
> +  END IF.
> +  loop startfy=starts(#-1) TO endfy .
> +    XSAVE OUTFILE 'C:\Users\David\TEMP\long.sav' / KEEP ID startfy
> rank
> endfy.
> +  end loop.
> end loop If #done.
> EXE.
> GET FILE 'C:\Users\David\TEMP\long.sav' .
>
> Bruce Weaver wrote
>> I expect there's some more elegant method, but it is late on a Friday
>> afternoon!
>>
>> new file.
>> dataset close all.
>> data list list / ID startFY rank endFY (4f5.0).
>> begin data
>> 1 2003 4 2003
>> 2 1985 5 1991
>> 2 1987 2 1991
>> 2 1990 1 1991
>> 3 1979 4 1980
>> end data.
>>
>> * I will need flags for First and Last records within an ID.
>>
>> match files
>>  file = * / by ID /
>>  FIRST = FirstRec / LAST = LastRec.
>> exe.
>>
>> * Sort cases in reverse order so I can use LAG.
>>
>> compute case = $casenum.
>> formats case (f5.0).
>> exe.
>> sort cases by case(d).
>>
>> ******************* .
>> if LastRec final = endFY.
>> if NOT LastRec final = lag(startFY) - 1.
>> formats final(f4.0).
>> ******************* .
>>
>> * Revert to original case order.
>>
>> sort cases by case.
>>
>> loop start = startFY to final.
>> xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
>> end loop.
>> execute.
>> get file = "C:\Temp\junk.sav".
>> formats start(f4.0).
>> list.
>>
>> OUTPUT:
>>
>> ID start  rank endFY
>>
>>     1  2003     4  2003
>>     2  1985     5  1991
>>     2  1986     5  1991
>>     2  1987     2  1991
>>     2  1988     2  1991
>>     2  1989     2  1991
>>     2  1990     1  1991
>>     2  1991     1  1991
>>     3  1979     4  1980
>>     3  1980     4  1980
>>
>> Number of cases read:  10    Number of cases listed:  10
>>
>>
>> David Wright-6 wrote
>>> I have a dataset reporting the start year, person rank and end year
>>> and
>>> need to create a repeating table by ID that fills in the intervening
>>> years carrying the rank forward until it changes.  I've used loops &
>>> do
>>> repeats before but never to add records so I'm not sure what is the
>>> best
>>> method.  I have listed below the original and requested data.
>>> Thanks in
>>> advance.
>>>
>>>
>>> Original data structure:
>>>
>>> ID, startFY, rank, endFY
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1987 2 1991
>>> 2 1990 1 1991
>>> 3 1979 4 1980
>>>
>>>
>>> new data structure needed:
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1986 5 1991
>>> 2 1987 2 1991
>>> 2 1988 2 1991
>>> 2 1989 2 1991
>>> 2 1990 1 1991
>>> 2 1991 1 1991
>>> 3 1979 4 1980
>>> 3 1980 4 1980
>>>
>>> =====================
>>> To manage your subscription to SPSSX-L, send a message to
>
>>> LISTSERV@.UGA
>
>>>  (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
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> --
> View this message in context:
> http://spssx-discussion.1045642.n5.nabble.com/add-cases-to-a-repeating-table-based-on-previous-values-tp5715774p5715777.html
> Sent from the SPSSX Discussion mailing list archive at Nabble.com.
>
> =====================
> 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: add cases to a repeating table based on previous values

wsu_wright
In reply to this post by wsu_wright
(resending this so ignore if you have received it)

Bruce/David,

Thanks for the quick reply.  Very interesting, two very different
approaches.  I follow the code up until the embedded xsave within the
loop, can you explain what is happening as it works through the loop
regarding the xsave.  Again, many thanks fellows, its always nice to
know that we have a community to fall back on when needing help.

Bruce-- your code worked in creating the new table structure.  David,
may have to tweak your code, it appears to be adding additional years
and not catching all the ranks.  I've listed below Bruce & David's
output file:

Original:
ID, sFY, rank, eFY
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980

Bruce's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    1       1991
2       1991    1       1991
3       1979    4       1980
3       1980    4       1980

David's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    5       1991
2       1988    5       1991
2       1989    5       1991
2       1990    5       1991
2       1991    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    2       1991
2       1991    2       1991
3       1979    4       1980
3       1980    4       1980


On Fri, Oct 19, 2012 at 5:17 PM, David Marso wrote:

> This is similar with downside of requiring knowledge of max number of
> records.  Doesn't require sorts etc.
> --
> data list list / ID startFY rank endFY (4f5.0).
> begin data
> 1 2003 4 2003
> 2 1985 5 1991
> 2 1987 2 1991
> 2 1990 1 1991
> 3 1979 4 1980
> end data.
> CASESTOVARS  /ID=ID /GROUPBY=VARIABLE.
> VECTOR starts=startfy.1 TO startfy.3 /ranks =rank.1 to rank.3 .
> compute #done=0.
> loop #=2 to 3.
> +  compute rank=ranks(#-1).
> +  DO IF NOT(MISSING(starts(#))).
> +    compute #end= starts(#).
> +  ELSE.
> +    compute #end=endfy.
> +    compute #done=1.
> +  END IF.
> +  loop startfy=starts(#-1) TO endfy .
> +    XSAVE OUTFILE 'C:\Users\David\TEMP\long.sav' / KEEP ID startfy
> rank
> endfy.
> +  end loop.
> end loop If #done.
> EXE.
> GET FILE 'C:\Users\David\TEMP\long.sav' .
>
> Bruce Weaver wrote
>> I expect there's some more elegant method, but it is late on a Friday
>> afternoon!
>>
>> new file.
>> dataset close all.
>> data list list / ID startFY rank endFY (4f5.0).
>> begin data
>> 1 2003 4 2003
>> 2 1985 5 1991
>> 2 1987 2 1991
>> 2 1990 1 1991
>> 3 1979 4 1980
>> end data.
>>
>> * I will need flags for First and Last records within an ID.
>>
>> match files
>>  file = * / by ID /
>>  FIRST = FirstRec / LAST = LastRec.
>> exe.
>>
>> * Sort cases in reverse order so I can use LAG.
>>
>> compute case = $casenum.
>> formats case (f5.0).
>> exe.
>> sort cases by case(d).
>>
>> ******************* .
>> if LastRec final = endFY.
>> if NOT LastRec final = lag(startFY) - 1.
>> formats final(f4.0).
>> ******************* .
>>
>> * Revert to original case order.
>>
>> sort cases by case.
>>
>> loop start = startFY to final.
>> xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
>> end loop.
>> execute.
>> get file = "C:\Temp\junk.sav".
>> formats start(f4.0).
>> list.
>>
>> OUTPUT:
>>
>> ID start  rank endFY
>>
>>     1  2003     4  2003
>>     2  1985     5  1991
>>     2  1986     5  1991
>>     2  1987     2  1991
>>     2  1988     2  1991
>>     2  1989     2  1991
>>     2  1990     1  1991
>>     2  1991     1  1991
>>     3  1979     4  1980
>>     3  1980     4  1980
>>
>> Number of cases read:  10    Number of cases listed:  10
>>
>>
>> David Wright-6 wrote
>>> I have a dataset reporting the start year, person rank and end year
>>> and
>>> need to create a repeating table by ID that fills in the intervening
>>> years carrying the rank forward until it changes.  I've used loops &
>>> do
>>> repeats before but never to add records so I'm not sure what is the
>>> best
>>> method.  I have listed below the original and requested data. Thanks
>>> in
>>> advance.
>>>
>>>
>>> Original data structure:
>>>
>>> ID, startFY, rank, endFY
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1987 2 1991
>>> 2 1990 1 1991
>>> 3 1979 4 1980
>>>
>>>
>>> new data structure needed:
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1986 5 1991
>>> 2 1987 2 1991
>>> 2 1988 2 1991
>>> 2 1989 2 1991
>>> 2 1990 1 1991
>>> 2 1991 1 1991
>>> 3 1979 4 1980
>>> 3 1980 4 1980
>>>
>>> =====================
>>> To manage your subscription to SPSSX-L, send a message to
>
>>> LISTSERV@.UGA
>
>>>  (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
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> --
> View this message in context:
> http://spssx-discussion.1045642.n5.nabble.com/add-cases-to-a-repeating-table-based-on-previous-values-tp5715774p5715777.html
> Sent from the SPSSX Discussion mailing list archive at Nabble.com.
>
> =====================
> 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: add cases to a repeating table based on previous values

David Marso
Administrator
"David,
may have to tweak your code, it appears to be adding additional years
and not catching all the ranks."
Fixed below...fairly simple fixes...

Oops my bad ;-)  Mods in Bold.

"can you explain what is happening as it works through the loop
regarding the xsave"

XSAVE is simply outputting a record to the designated file within the LOOP.
--  
data list list / ID startF rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.
CASESTOVARS  /ID=ID /GROUPBY=VARIABLE.
VECTOR starts=startf.1 TO startf.3 /ranks =rank.1 to rank.3 /stf(4).
RECODE startf.1 TO startf.3 (ELSE=COPY) INTO stf1 TO stf3.

compute #done=0.
loop #=2 to 4.
+  compute rank=ranks(#-1).
+  DO IF NOT(MISSING(stf(#))).
+    compute #end= stf(#)-1.
+  ELSE.
+    compute #end=endfy.
+    compute #done=1.
+  END IF.
+  loop startfy=stf(#-1) TO #end .
+    XSAVE OUTFILE 'C:\TEMP\long.sav' / KEEP ID startfy rank endfy.
+  end loop.
end loop If #done.
EXE.
GET FILE 'C:\TEMP\long.sav' .

David Wright-6 wrote
(resending this so ignore if you have received it)

Bruce/David,

Thanks for the quick reply.  Very interesting, two very different
approaches.  I follow the code up until the embedded xsave within the
loop, can you explain what is happening as it works through the loop
regarding the xsave.  Again, many thanks fellows, its always nice to
know that we have a community to fall back on when needing help.

Bruce-- your code worked in creating the new table structure.  David,
may have to tweak your code, it appears to be adding additional years
and not catching all the ranks.  I've listed below Bruce & David's
output file:

Original:
ID, sFY, rank, eFY
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980

Bruce's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    1       1991
2       1991    1       1991
3       1979    4       1980
3       1980    4       1980

David's code results:
1       2003    4       2003
2       1985    5       1991
2       1986    5       1991
2       1987    5       1991
2       1988    5       1991
2       1989    5       1991
2       1990    5       1991
2       1991    5       1991
2       1987    2       1991
2       1988    2       1991
2       1989    2       1991
2       1990    2       1991
2       1991    2       1991
3       1979    4       1980
3       1980    4       1980


On Fri, Oct 19, 2012 at 5:17 PM, David Marso wrote:

> This is similar with downside of requiring knowledge of max number of
> records.  Doesn't require sorts etc.
> --
> data list list / ID startFY rank endFY (4f5.0).
> begin data
> 1 2003 4 2003
> 2 1985 5 1991
> 2 1987 2 1991
> 2 1990 1 1991
> 3 1979 4 1980
> end data.
> CASESTOVARS  /ID=ID /GROUPBY=VARIABLE.
> VECTOR starts=startfy.1 TO startfy.3 /ranks =rank.1 to rank.3 .
> compute #done=0.
> loop #=2 to 3.
> +  compute rank=ranks(#-1).
> +  DO IF NOT(MISSING(starts(#))).
> +    compute #end= starts(#).
> +  ELSE.
> +    compute #end=endfy.
> +    compute #done=1.
> +  END IF.
> +  loop startfy=starts(#-1) TO endfy .
> +    XSAVE OUTFILE 'C:\Users\David\TEMP\long.sav' / KEEP ID startfy
> rank
> endfy.
> +  end loop.
> end loop If #done.
> EXE.
> GET FILE 'C:\Users\David\TEMP\long.sav' .
>
> Bruce Weaver wrote
>> I expect there's some more elegant method, but it is late on a Friday
>> afternoon!
>>
>> new file.
>> dataset close all.
>> data list list / ID startFY rank endFY (4f5.0).
>> begin data
>> 1 2003 4 2003
>> 2 1985 5 1991
>> 2 1987 2 1991
>> 2 1990 1 1991
>> 3 1979 4 1980
>> end data.
>>
>> * I will need flags for First and Last records within an ID.
>>
>> match files
>>  file = * / by ID /
>>  FIRST = FirstRec / LAST = LastRec.
>> exe.
>>
>> * Sort cases in reverse order so I can use LAG.
>>
>> compute case = $casenum.
>> formats case (f5.0).
>> exe.
>> sort cases by case(d).
>>
>> ******************* .
>> if LastRec final = endFY.
>> if NOT LastRec final = lag(startFY) - 1.
>> formats final(f4.0).
>> ******************* .
>>
>> * Revert to original case order.
>>
>> sort cases by case.
>>
>> loop start = startFY to final.
>> xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
>> end loop.
>> execute.
>> get file = "C:\Temp\junk.sav".
>> formats start(f4.0).
>> list.
>>
>> OUTPUT:
>>
>> ID start  rank endFY
>>
>>     1  2003     4  2003
>>     2  1985     5  1991
>>     2  1986     5  1991
>>     2  1987     2  1991
>>     2  1988     2  1991
>>     2  1989     2  1991
>>     2  1990     1  1991
>>     2  1991     1  1991
>>     3  1979     4  1980
>>     3  1980     4  1980
>>
>> Number of cases read:  10    Number of cases listed:  10
>>
>>
>> David Wright-6 wrote
>>> I have a dataset reporting the start year, person rank and end year
>>> and
>>> need to create a repeating table by ID that fills in the intervening
>>> years carrying the rank forward until it changes.  I've used loops &
>>> do
>>> repeats before but never to add records so I'm not sure what is the
>>> best
>>> method.  I have listed below the original and requested data. Thanks
>>> in
>>> advance.
>>>
>>>
>>> Original data structure:
>>>
>>> ID, startFY, rank, endFY
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1987 2 1991
>>> 2 1990 1 1991
>>> 3 1979 4 1980
>>>
>>>
>>> new data structure needed:
>>>
>>> 1 2003 4 2003
>>> 2 1985 5 1991
>>> 2 1986 5 1991
>>> 2 1987 2 1991
>>> 2 1988 2 1991
>>> 2 1989 2 1991
>>> 2 1990 1 1991
>>> 2 1991 1 1991
>>> 3 1979 4 1980
>>> 3 1980 4 1980
>>>
>>> =====================
>>> To manage your subscription to SPSSX-L, send a message to
>
>>> LISTSERV@.UGA
>
>>>  (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
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> --
> View this message in context:
> http://spssx-discussion.1045642.n5.nabble.com/add-cases-to-a-repeating-table-based-on-previous-values-tp5715774p5715777.html
> Sent from the SPSSX Discussion mailing list archive at Nabble.com.
>
> =====================
> 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
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
Re-tweak
(Refactor DO IF ELSE IF into MIN and move to inner LOOP,
evaluate #done flag within END LOOP IF)
--
data list list / ID startF rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.
CASESTOVARS  /ID=ID .
VECTOR starts=startf.1 TO startf.3
            /ranks =rank.1 to rank.3
            /stf(4).
RECODE startf.1 TO startf.3 (ELSE=COPY) INTO stf1 TO stf3.
LOOP #=2 to 4.
+  COMPUTE rank=ranks(#-1).
+  LOOP startfy=stf(#-1) TO MIN(stf(#)-1,endfy) .
+    XSAVE OUTFILE 'C:\TEMP\long.sav' / KEEP ID startfy rank endfy.
+  END LOOP.
END LOOP IF MISSING(stf(#)).
EXE.
GET FILE 'C:\TEMP\long.sav' .
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
ReRe-Tweak...Far superior to my 3 previous stabs ;-)
What would Art call this?  Code refinement?
---
SPLIT FILE BY id.
CREATE start_x=lead(startf,1).
SPLIT FILE OFF.
LOOP startfy=startf TO MIN(start_x-1,endFY).
+ XSAVE OUTFILE 'C:\TEMP\longx.sav'/ KEEP ID startfy rank endfy.
END LOOP.
EXE.
GET FILE 'C:\TEMP\longx.sav'.
---
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

Bruce Weaver
Administrator
David Marso wrote
ReRe-Tweak...Far superior to my 3 previous stabs ;-)
What would Art call this?  Code refinement?
Here's a refinement of the method I posted.  I'd forgotten about SHIFT VALUES, which was added in v17 or so.  It eliminates the sorting I had in my original solution.


new file.
dataset close all.
data list list / ID startFY rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.

SHIFT VALUES variable = ID result = NextID LEAD=1.
SHIFT VALUES variable = startFY result = NextStart LEAD=1.
DO IF ID EQ NextID.
- compute final = NextStart - 1.
ELSE.  
- compute final = endFY.
END IF.
* NextID is missing on the final row of the data file.
IF missing(NextID) final = endFY.
EXECUTE.

loop start = startFY to final.
xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
end loop.
execute.
get file = "C:\Temp\junk.sav".
formats start(f4.0).
list.

OUTPUT:

  ID start  rank endFY
 
    1  2003     4  2003
    2  1985     5  1991
    2  1986     5  1991
    2  1987     2  1991
    2  1988     2  1991
    2  1989     2  1991
    2  1990     1  1991
    2  1991     1  1991
    3  1979     4  1980
    3  1980     4  1980
 
Number of cases read:  10    Number of cases listed:  10


NOTE on SHIFT VALUES:  I thought I might be able to create NextID and NextStart with a single SHIFT VALUES command like this:

SHIFT VALUES variable = ID startFY result = NextID NextStart LEAD=1.

But that generated an error message--something about RESULT needing to specify a single variable.  That seems rather inconsistent with how other procedures can take lists of variables (e.g., RECODE).
--
Bruce Weaver
bweaver@lakeheadu.ca
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

PLEASE NOTE THE FOLLOWING: 
1. My Hotmail account is not monitored regularly. To send me an e-mail, please use the address shown above.
2. The SPSSX Discussion forum on Nabble is no longer linked to the SPSSX-L listserv administered by UGA (https://listserv.uga.edu/).
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

Art Kendall
In reply to this post by David Marso
I would call this "the ordinary course of events" in analysis or any other communication, one reconsiders and rewrites one approach.  I try to emphasize right from the beginning the value of using syntax and the value of learning how others approach the same problem.

I also call it the "benefit of team idea building".

This conversation (thread) is an example of people seeing other approaches and refining one's  own process.  It is also an example of how using syntax facilitates communication to others and to oneself.

Thank you for this opportunity to get on  my soapboxes.
Art Kendall
Social Research Consultants
On 10/24/2012 7:39 AM, David Marso wrote:
ReRe-Tweak...Far superior to my 3 previous stabs ;-)
What would Art call this?  Code refinement?
---
SPLIT FILE BY id.
CREATE start_x=lead(startf,1).
SPLIT FILE OFF.
LOOP startfy=startf TO MIN(start_x-1,endFY).
+ XSAVE OUTFILE 'C:\TEMP\longx.sav'/ KEEP ID startfy rank endfy.
END LOOP.
EXE.
GET FILE 'C:\TEMP\longx.sav'.
---



-----
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
--
View this message in context: http://spssx-discussion.1045642.n5.nabble.com/add-cases-to-a-repeating-table-based-on-previous-values-tp5715774p5715832.html
Sent from the SPSSX Discussion mailing list archive at Nabble.com.

=====================
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
Art Kendall
Social Research Consultants
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
In reply to this post by Bruce Weaver
One more approach which avoids the creation of any
external file at the expense of the momentary overhead of a wide file.
data list list / ID startF rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
4 1971 2 2010
4 1985 3 2010
4 1990 4 2010
4 1999 5 2010
end data.

** Avoiding external file **.
SPLIT FILE BY id.
CREATE start_x=lead(startf,1).
SPLIT FILE OFF.
NUMERIC Y1971 TO Y2010.
VECTOR Y =Y1971 TO Y2010.
LOOP startfy=startf TO MIN(start_x-1,endFY).
COMPUTE Y(startfy-1970)=startfy.
END LOOP.
VARSTOCASES
     /MAKE trans1 FROM y1971 TO y2010
     /KEEP =  id rank endfy.


Bruce Weaver wrote
David Marso wrote
ReRe-Tweak...Far superior to my 3 previous stabs ;-)
What would Art call this?  Code refinement?
Here's a refinement of the method I posted.  I'd forgotten about SHIFT VALUES, which was added in v17 or so.  It eliminates the sorting I had in my original solution.


new file.
dataset close all.
data list list / ID startFY rank endFY (4f5.0).
begin data
1 2003 4 2003
2 1985 5 1991
2 1987 2 1991
2 1990 1 1991
3 1979 4 1980
end data.

SHIFT VALUES variable = ID result = NextID LEAD=1.
SHIFT VALUES variable = startFY result = NextStart LEAD=1.
DO IF ID EQ NextID.
- compute final = NextStart - 1.
ELSE.  
- compute final = endFY.
END IF.
* NextID is missing on the final row of the data file.
IF missing(NextID) final = endFY.
EXECUTE.

loop start = startFY to final.
xsave outfile = "C:\Temp\junk.sav" /keep = id start rank endFY .
end loop.
execute.
get file = "C:\Temp\junk.sav".
formats start(f4.0).
list.

OUTPUT:

  ID start  rank endFY
 
    1  2003     4  2003
    2  1985     5  1991
    2  1986     5  1991
    2  1987     2  1991
    2  1988     2  1991
    2  1989     2  1991
    2  1990     1  1991
    2  1991     1  1991
    3  1979     4  1980
    3  1980     4  1980
 
Number of cases read:  10    Number of cases listed:  10


NOTE on SHIFT VALUES:  I thought I might be able to create NextID and NextStart with a single SHIFT VALUES command like this:

SHIFT VALUES variable = ID startFY result = NextID NextStart LEAD=1.

But that generated an error message--something about RESULT needing to specify a single variable.  That seems rather inconsistent with how other procedures can take lists of variables (e.g., RECODE).
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
In reply to this post by Bruce Weaver
BW:
**NOTE on SHIFT VALUES:  I thought I might be able to create NextID and NextStart with a single SHIFT VALUES command like this:
**SHIFT VALUES variable = ID startFY result = NextID NextStart LEAD=1.

FM:
SHIFT VALUES VARIABLE=varname RESULT=varname {LEAD=non-negative integer}
{LAG=non-negative integer }
{SHIFT=integer }
[/VARIABLE=varname...]

DM:
SHIFT VALUES
          VARIABLE = id         RESULT = NextID    LEAD=1
        / VARIABLE = startFY RESULT = NextStart LEAD=1.

OTOH: SPLIT FILE /CREATE/VECTOR-LOOP/VARSTOCASES is likely what I would use in production.
I try to avoid writing to the file system whenever possible (my typical code goes to clients and their clients and who the hell knows what they are using and what valid paths exist etc).
I prefer CREATE because it is portable back to even ancient versions .
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

Bruce Weaver
Administrator
D'oh!  I should have spent a bit more time looking at the FM!  Thanks David.


David Marso wrote
BW:
**NOTE on SHIFT VALUES:  I thought I might be able to create NextID and NextStart with a single SHIFT VALUES command like this:
**SHIFT VALUES variable = ID startFY result = NextID NextStart LEAD=1.

FM:
SHIFT VALUES VARIABLE=varname RESULT=varname {LEAD=non-negative integer}
{LAG=non-negative integer }
{SHIFT=integer }
[/VARIABLE=varname...]

DM:
SHIFT VALUES
          VARIABLE = id         RESULT = NextID    LEAD=1
        / VARIABLE = startFY RESULT = NextStart LEAD=1.

OTOH: SPLIT FILE /CREATE/VECTOR-LOOP/VARSTOCASES is likely what I would use in production.
I try to avoid writing to the file system whenever possible (my typical code goes to clients and their clients and who the hell knows what they are using and what valid paths exist etc).
I prefer CREATE because it is portable back to even ancient versions .
--
Bruce Weaver
bweaver@lakeheadu.ca
http://sites.google.com/a/lakeheadu.ca/bweaver/

"When all else fails, RTFM."

PLEASE NOTE THE FOLLOWING: 
1. My Hotmail account is not monitored regularly. To send me an e-mail, please use the address shown above.
2. The SPSSX Discussion forum on Nabble is no longer linked to the SPSSX-L listserv administered by UGA (https://listserv.uga.edu/).
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

David Marso
Administrator
Note also:
Operations
* If split file processing is on, the scope of the shift is limited to each split group. A shift value
cannot be obtained from a case in a preceding or subsequent split group.
...
* The value of the result variable is set to system-missing for the first or last n cases in the
dataset or split group, where n is the number of cases specified on LEAD, LAG, or SHIFT.
...

--
Bruce Weaver wrote
D'oh!  I should have spent a bit more time looking at the FM!  Thanks David.


David Marso wrote
BW:
**NOTE on SHIFT VALUES:  I thought I might be able to create NextID and NextStart with a single SHIFT VALUES command like this:
**SHIFT VALUES variable = ID startFY result = NextID NextStart LEAD=1.

FM:
SHIFT VALUES VARIABLE=varname RESULT=varname {LEAD=non-negative integer}
{LAG=non-negative integer }
{SHIFT=integer }
[/VARIABLE=varname...]

DM:
SHIFT VALUES
          VARIABLE = id         RESULT = NextID    LEAD=1
        / VARIABLE = startFY RESULT = NextStart LEAD=1.

OTOH: SPLIT FILE /CREATE/VECTOR-LOOP/VARSTOCASES is likely what I would use in production.
I try to avoid writing to the file system whenever possible (my typical code goes to clients and their clients and who the hell knows what they are using and what valid paths exist etc).
I prefer CREATE because it is portable back to even ancient versions .
Please reply to the list and not to my personal email.
Those desiring my consulting or training services please feel free to email me.
---
"Nolite dare sanctum canibus neque mittatis margaritas vestras ante porcos ne forte conculcent eas pedibus suis."
Cum es damnatorum possederunt porcos iens ut salire off sanguinum cliff in abyssum?"
Reply | Threaded
Open this post in threaded view
|

Re: add cases to a repeating table based on previous values

wsu_wright
In reply to this post by wsu_wright
David & Bruce,

Just closing this thread with a huge thank you, I've revised my code to
reflect your latest iterations.  As is always the case on this listserv,
a solution is provided as well as an education!

David,



On Wed, Oct 24, 2012 at 10:43 AM, David Marso wrote:

> Note also:
> *Operations*
> * If split file processing is on, the scope of the shift is limited to
> each
> split group. A shift value
> cannot be obtained from a case in a preceding or subsequent split
> group.
> ...
> * The value of the result variable is set to system-missing for the
> first or
> last n cases in the
> dataset or split group, where n is the number of cases specified on
> LEAD,
> LAG, or SHIFT.
> ...
>
> --
>
> Bruce Weaver wrote
>> D'oh!  I should have spent a bit more time looking at the FM!  Thanks
>> David.
>>
>> David Marso wrote
>>> BW:
>>> **NOTE on SHIFT VALUES:  I thought I might be able to create NextID
>>> and
>>> NextStart with a single SHIFT VALUES command like this:
>>> **SHIFT VALUES variable = ID startFY result = NextID NextStart
>>> LEAD=1.
>>>
>>> FM:
>>> SHIFT VALUES VARIABLE=varname RESULT=varname {LEAD=non-negative
>>> integer}
>>> {LAG=non-negative integer }
>>> {SHIFT=integer }
>>> [/VARIABLE=varname...]
>>>
>>> DM:
>>> SHIFT VALUES
>>>           VARIABLE = id         RESULT = NextID    LEAD=1
>>>         / VARIABLE = startFY RESULT = NextStart LEAD=1.
>>>
>>> OTOH: SPLIT FILE /CREATE/VECTOR-LOOP/VARSTOCASES is likely what I
>>> would
>>> use in production.
>>> I try to avoid writing to the file system whenever possible (my
>>> typical
>>> code goes to clients and their clients and who the hell knows what
>>> they
>>> are using and what valid paths exist etc).
>>> I prefer CREATE because it is portable back to even ancient versions
>>> .
>
>
>
>
>
> -----
> Please reply to the list and not to my personal email.
> Those desiring my consulting or training services please feel free to
> email me.
> --
> View this message in context:
> http://spssx-discussion.1045642.n5.nabble.com/add-cases-to-a-repeating-table-based-on-previous-values-tp5715774p5715843.html
> Sent from the SPSSX Discussion mailing list archive at Nabble.com.
>
> =====================
> 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