Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Re: st: Generating days eligible when eligibility changes over time


From   Nick Cox <[email protected]>
To   "[email protected]" <[email protected]>
Subject   Re: Re: st: Generating days eligible when eligibility changes over time
Date   Mon, 10 Mar 2014 18:22:16 +0000

Thanks for reporting back.

I guess I am puzzled that the birthday fudge remains when there is a
way of doing it without fudge!

A more positive point is that insofar as the problem just requires
working in months, you could reduce the birthdays to monthly dates and
then work with the idea that the next birthday is always just 12
months later.

A wider point is that repeated study of the Stata help on dates and
times is not only necessary but also useful. It's common that people
make up their own fudges for already solved problems.

Nick
[email protected]


On 10 March 2014 16:42, Brill, Robert <[email protected]> wrote:
> Thanks for the help with birthdays--I had used rough code(birthday+(365.25*`age')) to generate the 'turned`age'' variable and your snippet is very helpful to do it correctly.
>
> The survey date is the date that the individuals were contacted--the dataset is survey, rather than administrative. The goal is to see how much time an child had been eligible between his birth and the date that he was surveyed.
>
> Also, very embarrassing that I forgot about the branching if in Stata--I had gotten too caught up in the other moving parts of the puzzle. However, I realized that because the dates of eligibility are scalars, there was no need to call to the dataset to branch, but rather to loop over all of the months in each year and branch based on those to generate the indicator variables.
>
> I also went back and noticed that the program is paid monthly and individuals are paid the benefit in the month of their birthday, so it's only important to find the number of months as a dose (in fact the "actual" dose, rather than the intended dose, is also measured in months)
>
> Here's the code I ended up using:
>
> forval y=1998/2010 {
> forval m=1/12 {
>         local start "mdy(01,01,1998)"
>                 local p1 "mdy(04,01,2003)"
>                 local p2 "mdy(01,01,2004)"
>                 local p3 "mdy(01,01,2005)"
>                 local p4 "mdy(01,01,2008)"
>                 local p5 "mdy(01,01,2010)"
>         local date = mdy(`m',01,`y')
>
>         if `date'<=`p1' {
>
>         g drop`m'`y'=(((`date'-birthday)/365.25)<7)
>         }
>
>         else if `date'>`p1' & `date'<=`p2' {
>         g drop`m'`y'=(((`date'-birthday)/365.25)<9)
>         }
>
>         else if `date'>`p2' & `date'<=`p3' {
>         g drop`m'`y'=(((`date'-birthday)/365.25)<11)
>         }
>
>         else if `date'>`p3' & `date'<=`p4' {
>         g drop`m'`y'=(((`date'-birthday)/365.25)<14)
>         }
>
>         else if `date'>`p4' & `date'<=`p5' {
>         g drop`m'`y'=(((`date'-birthday)/365.25)<15)
>         }
>
>         else if `date'>`p5'  {
>         g drop`m'`y'=(((`date'-birthday)/365.25)<18)
>         }
>
>         }
>         }
>
>
> egen intdose=rowtotal(drop*)
> replace intdose=intdose/12
>
> drop drop*
>
> From an academic perspective, I'm still interested in how I might do this for a daily dosage, however, and I was thinking that the best way might be to loop over the days of the year (using dofy) and evaluate eligibility on each day. This seems like very inefficient code, however, and would exceed the limit of some versions of Stata, especially if the period of eligibility is long.  Maybe I'll look around stackexchange for a similar problem, or perhaps keep slogging along and write something generalizable.
>
>
>
> Once again, thanks for your help with the birthday stuff-I'm sure that will come in handy in the future.
>
> Best,
>
> Rob Brill
>
> Date: Fri, 7 Mar 2014 13:02:47 +0000
> From: Nick Cox <[email protected]>
> Subject: Re: st: Generating days eligible when eligibility changes over time
>
> This is an interesting problem.
>
> I haven't tried understanding your code exactly, but note that you
> seem to be confusing the -if- command and the -if- qualifier, perhaps
> due to some previous or concurrent life as a SAS user.
>
> 0. I don't think I understood about the "survey date" and when that was.
>
> 1. In your sample data, birthdays often look off, so that (e.g.) the
> first two individuals capriciously celebrate their birthdays a day
> earlier than usual in some or all cases.
>
> 06sep1995 05sep2002 05sep2004 05sep2006
> 06dec1994 05dec2001 06dec2003 05dec2005
>
> Birthdays in my view are better calculated by Stata. I know of one
> predictable problem and presume that people born on 29 February are
> deemed to celebrate their birthday on 28 February when it's not a leap
> year.
>
> 2. The exact rule could be that eligibility ends (a) on a particular
> birthday or (b) on the day before, but I'll let you worry about that
> and add or subtract 1 according to whether code is correct or off.
>
> This code gives some technique that may help.
>
> clear
> input str9 birthday
> 01jan1950
> 01jan1995
> 01apr1995
> 01jan1997
> 01apr1999
> 31dec1991
> end
>
> gen dbirthday = date(birthday, "DMY")
>
> local start1 = date("01jan1998", "DMY")
> local limit1 = 7
> local start2 = date("01apr2003", "DMY")
> local limit2 = 9
> local start3 = date("01jan2004", "DMY")
> local limit3 = 11
> local start4 = date("01jan2005", "DMY")
> local limit4 = 14
> local start5 = date("01jan2008", "DMY")
> local limit5 = 15
> local start6 = date("01jan2010", "DMY")
> local limit6 = 18
>
> gen limitdate = .
> gen eligible = 0
>
> qui forval j = 1/6 {
>     replace limitdate = mdy(month(dbirthday), day(dbirthday),
> year(dbirthday) + `limit`j'')
>     replace limitdate = mdy(2, 28, year(dbirthday)) if
> missing(limitdate) & !missing(dbirthday)
>     replace eligible = eligible + max(0, limitdate - `start`j'')
> }
>
> list , sep(0)
>
> I would always recommend working with a test dataset for which the
> correct answers can be calculated independently.
>
> Nick
> [email protected]
>
>
> On 7 March 2014 00:19, Brill, Robert <[email protected]> wrote:
>> Hi Listers,
>>
>> Iım working on a project in which I am generating an ³intended dosage²
>> variable equal to the number of days that a person was
>> eligible for a cash grant program.  In short, Iıd like to know how many
>> days a child was eligible for the program between the program start and
>> the survey date. Eligibility is based on being under an age cutoff. The
>> government in question, however, changed the eligibility age 4 times over
>> the course of the period of interest (1998-2010).
>>
>> The program began on 01jan1998, and was available to children under 7. On
>> 01apr2003 the eligibility was increased to 9, on  01jan2004 to 11, on
>> 01jan2005 to 14, on 01jan2008 to 15, and on 01jan2010 to 18.
>>
>> Therefore, if an individual turned 7 after the first eligibility change
>> occurred, she was eligible from the beginning of the program in 1998 until
>> the date of the survey in 2010. However, if she turned 7 before the
>> change, she is only eligible for the number of days from the beginning of
>> the program until the date she turned 7. Itıs also possible  that a
>> different child with a different birthday would fluctuate back and forth
>> in eligibility as the changes occurred (depending on her birthday,
>> obviously).
>>
>> To generalize to all cases, Iıve considered generating a dose variable for
>> each of the periods (1998-2003, 2003-2004, 2004-2005, 2005-2008, and
>> 2008-2010) which uses if and if else statements to take all of the types
>> of cases into account when subtracting birthdays and eligibility change
>> days etc., or, alternatively, generating a couple hundred month indicators
>> (or a few thousand days) that are 1 if an individual was eligible in that
>> month (or day), then calculating the row total to tell me the number of
>> months (or days) eligible.
>>
>> However, Iıd much prefer to have a fully accurate measure to the day, and
>> it seems a bit too crazy to generate all of those indicators when thereıs
>> likely another way, but I havenıt been able to think my way out of my
>> current funk.
>>
>> The variable ³birthday² is a %td formatted individual birthday. ³turned7²
>> is the date that the individual turned 7 (and exists for each age,
>> turned9, etc.).
>>
>> Right now, the code looks like:
>>
>>
>> ** Input some example data
>> input str9 birthday str9 turned7 str9 turned9 str9 turned11
>> 06sep1995 05sep2002 05sep2004 05sep2006
>> 06dec1994 05dec2001 06dec2003 05dec2005
>> 23oct1995 22oct2002 22oct2004 22oct2006
>> 01dec1994 30nov2001 01dec2003 30nov2005
>> 08sep1994 07sep2001 08sep2003 07sep2005
>> 26jun1995 25jun2002 25jun2004 25jun2006
>> 10nov1995 09nov2002 09nov2004 09nov2006
>> 12feb1994 11feb2001 12feb2003 11feb2005
>> 16nov1995 15nov2002 15nov2004 15nov2006
>> 10feb1994 09feb2001 10feb2003 09feb2005
>> 01sep1994 31aug2001 01sep2003 31aug2005
>> 26oct1994 25oct2001 26oct2003 25oct2005
>> 21nov1994 20nov2001 21nov2003 20nov2005
>> 03nov1994 02nov2001 03nov2003 02nov2005
>> 10mar1994 09mar2001 10mar2003 09mar2005
>> 31oct1994 30oct2001 31oct2003 30oct2005
>> 08aug1994 07aug2001 08aug2003 07aug2005
>> 21dec1994 20dec2001 21dec2003 20dec2005
>> 10may1994 09may2001 10may2003 09may2005
>> 19apr1994 18apr2001 19apr2003 18apr2005
>> 05nov1994 04nov2001 05nov2003 04nov2005
>> 18dec1995 17dec2002 17dec2004 17dec2006
>> 24may1995 23may2002 23may2004 23may2006
>> 15aug1994 14aug2001 15aug2003 14aug2005
>> 05apr1995 04apr2002 04apr2004 04apr2006
>> end
>>
>> ** format inputted data
>> foreach v of varlist *{
>> g td`v'=date(`v', "DMY")
>> drop `v'
>> rename td`v' `v'
>> format `v' %td
>> }
>>
>>
>> **generate dose by period vars
>>
>> forval i=1/5 {
>>     g p`i'dose=.
>>     }
>>
>>
>> ** use a bunch of if/else statements to generate dosage by period to be
>> summed later
>> foreach e in 7  {
>>         local start "mdy(01,01,1998)"
>>         local p1 "mdy(04,01,2003)"
>>         local p2 "mdy(01,01,2004)"
>>         local p3 "mdy(01,01,2005)"
>>         local p4 "mdy(01,01,2008)"
>>         local p5 "mdy(01,01,2010)"
>>
>>         if turned7>`p1' {
>>             replace p1dose=`p1'-birthday
>>         }
>>
>>         else if turned7<`p1' & birthday>`start' {
>>             replace p1dose=turned7-birthday
>>         }
>>
>>         else if turned7<`p1' & birthday<`start' {
>>             replace p1dose=turned7-`start'
>>         }
>>
>>         if turned9>`p2ı & turned7>`p1ı {
>>             replace p2dose=`p2ı-`p1ı
>>         }
>>
>>         else if turned9<`p2ı & turned9>`p1ı {
>>             replace p2dose=turned9-`p1ı
>>         }
>> ** etc etc etc
>>
>>
>>
>> Or alternatively, the code could look like
>>
>>
>> forval m=1/12 {
>>
>> forval y=1998/2012 {
>>
>>     if `yı<2003 { //this has a problem because of the april thing but you
>> get the idea
>>         g drop`mı`yı=(((mdy(`mı,01,`yı)-birthday)/365.25)<7)
>>         }
>>
>>     else if  `yı >2002 & `yı<2005 {
>> ** etc etc etc
>> }
>>
>>
>>
>> While Iım not entirely opposed to doing one of these ways, Iım wondering
>> if there is some obvious or less-obvious way to go through this in a more
>> efficient way or that perhaps requires less opaque code.
>>
>> Any hints, tips, or tricks are very welcome and will be received with
>> extreme gratitude, Iıve been banging my head against a wall on this for a
>> while now and would love to hear new perspectives on the problem.
>>
>>
>> Thanks greatly for your time, and for all the great help that Iıve gotten
>> in the past by searching the archive.
>
> *
> *   For searches and help try:
> *   http://www.stata.com/help.cgi?search
> *   http://www.stata.com/support/faqs/resources/statalist-faq/
> *   http://www.ats.ucla.edu/stat/stata/
>
> ------------------------------
>
> *
> *   For searches and help try:
> *   http://www.stata.com/help.cgi?search
> *   http://www.stata.com/support/faqs/resources/statalist-faq/
> *   http://www.ats.ucla.edu/stat/stata/

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/faqs/resources/statalist-faq/
*   http://www.ats.ucla.edu/stat/stata/


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index