Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Calculate age from date of birth and test-date

    Dear all,

    As I am proceeding through my databases, I figured I want to know at which age a patient has gotten a certain scan and also, how old the patient was when they draw blood from him/her.

    In order to calculate this, I read the datetime pdf's, this forum and I downloaded the file "personage" from Nick Cox. However, I can't get my calculation right.

    These variables am I using: dob1 (double, %tc) and scandate1 (double, %tc).

    I tried these different commands:

    dofc(dob1)
    format dob1 %tm
    personage dob1 scandate1, generate(age)
    gen age= (dob1-scandate1)/365.25


    these commands result at its best in the variable age -4.58e+09.

    So I'm feeling I know a little about the possible commands now, but can't get my head around the best command to use.

    Thanks for your kind help!

    Mariska

  • #2
    The help for personage (SSC; you are asked to explain where programs come from) explains that it feeds on daily date variables, so feeding it anything else will just produce nonsense at best.

    Indeed it is documented explicitly that

    personage is not suitable for date-times measured in milliseconds. Use dofc() or dofC() as appropriate first to convert to daily dates.
    Of your commands (assuming that you typed what you report; you should report what Stata typed in return)

    Code:
     
    dofc(dob1)
    by itself will fail as illegal, as isolated function calls are not allowed in Stata.

    Code:
     
    format dob1 %tm
    is legal in itself but just attempts to change the display format to a monthly date format that has nothing to do with this problem. Note that a date-time such as for around now is an integer with units of milliseconds and typical value of the order of a trillion:

    Code:
     
    . di %18.0f clock("23 Mar 2015 14:30:00", "DMY hms")
         1742740200000
    so that, interpreted as a monthly date, as the %tm format instructs, you are showing that number of months away from January 1960, which is still, pretty much, of the order of a trillion years in the future.

    All that aside, changing the display format changes nothing but the display format and can not possibly help here.

    But the first idea was the best. Try

    Code:
     
    gen d_dob1 = dofc(dob1)
    gen d_scandate1 = dofc(scandate1) 
    personage d_dob1 d_scandate1, gen(age)


    Comment


    • #3
      Originally posted by Nick Cox View Post
      The help for personage (SSC; you are asked to explain where programs come from) explains that it feeds on daily date variables, so feeding it anything else will just produce nonsense at best.

      Indeed it is documented explicitly that



      Of your commands (assuming that you typed what you report; you should report what Stata typed in return)

      Code:
      dofc(dob1)
      by itself will fail as illegal, as isolated function calls are not allowed in Stata.

      Code:
      format dob1 %tm
      is legal in itself but just attempts to change the display format to a monthly date format that has nothing to do with this problem. Note that a date-time such as for around now is an integer with units of milliseconds and typical value of the order of a trillion:

      Code:
      . di %18.0f clock("23 Mar 2015 14:30:00", "DMY hms")
      1742740200000
      so that, interpreted as a monthly date, as the %tm format instructs, you are showing that number of months away from January 1960, which is still, pretty much, of the order of a trillion years in the future.

      All that aside, changing the display format changes nothing but the display format and can not possibly help here.

      But the first idea was the best. Try

      Code:
      gen d_dob1 = dofc(dob1)
      gen d_scandate1 = dofc(scandate1)
      personage d_dob1 d_scandate1, gen(age)

      Dear Nick,

      Thank you for your clarification of the codes and especially for the last code, as this one worked just fine.

      Thinking furter: as I want to repeat the last block of codes for patiens who had multiple scans (for instance 6 scans per patient, all coded as: scandate1, scandate2, and so on) would a foreach or forvalues loop be a time-saving way to let STATA make these calculations?

      Comment


      • #4
        Yes, in principle, a loop over several variables should work fine here in Stata. STATA I don't know about.

        Comment


        • #5
          Originally posted by Nick Cox View Post
          Yes, in principle, a loop over several variables should work fine here in Stata. STATA I don't know about.
          Great, then I will try to create such a loop. And excuse me for keeping the caps-lock on while typing Stata.

          Comment


          • #6
            Dear Nick,

            I was using the suggested code:
            gen d_dob1 = dofc(dob1) gen d_scandate1 = dofc(scandate1) personage d_dob1 d_scandate1, gen(age) Now I came across a part of the database which describes the dat of birth (dob) in long, %tdD_m_Y, instead of double, %tc. Of course, your SSC personage does not work, because of the warning: warning: d_dob1 not formatted as daily date
            dob1 d_dob1 scandate1 d_scandate1 age
            17 Oct 97 0 11-8-2010 13:12 18485 50

            So the SSC personage output does result in an age, but this is false (see above). The other variable scandate1 is still double, %tc, which was changed succesfully with the dofc() command.

            How can I best change the date of birth (long, %tdD_m_Y) into a format that can work while using the SSC personage?

            P.S. I made a nice table with the output, put unfortunately it didn't paste properly on the forum.
            Last edited by Mariska Snel; 24 Mar 2015, 05:01.

            Comment


            • #7
              This was your code and this is how to present it readably using CODE delimiters:

              Code:
              gen d_dob1 = dofc(dob1)
              gen d_scandate1 = dofc(scandate1)
              personage d_dob1 d_scandate1, gen(age)
              Note that a warning is not an error. A warning is a warning and does not result in termination of a program. So the conclusion "Of course, your SSC personage does not work" might be correct, but the logic is fallacious if the signal was just a warning.

              I can't work out what your data are like. For example, I see two lines supposedly showing data. What are we supposed to see here? I see one date that is "17 Oct 970", so something is wrong.

              This is why we have advice explaining how to present readable questions.

              Here is a reproducible example with proof of concept:

              Code:
              . clear
              
              . set obs 1
              obs was 0, now 1
              
              . gen double bdatetime = clock("21 January 1952 11:15:00", "DMY hms")
              
              . gen double scdatetime = clock("23 March 2015 11:15:00", "DMY hms")
              
              . gen bddate = dofc(bdatetime)
              
              . gen scddate = dofc(scdatetime)
              
              . format *datetime %tc
              
              . format *ddate %td
              
              . personage bddate scddate, gen(age)
              (0 real changes made)
              (0 real changes made)
              (0 real changes made)
              
              . l
              
                   +-----------------------------------------------------------------------+
                   |          bdatetime           scdatetime      bddate     scddate   age |
                   |-----------------------------------------------------------------------|
                1. | 21jan1952 11:15:00   23mar2015 11:15:00   21jan1952   23mar2015    63 |
                   +-----------------------------------------------------------------------+
              Your date of birth variable is fine for the purposes of personage.




              Last edited by Nick Cox; 24 Mar 2015, 05:26.

              Comment


              • #8
                Dear Nick,

                Learned a lot from these topics! I talked it over with a collegue too and finally this is the code which worked best for me

                Code:
                gen eventdate = dofc( scandate)
                format eventdate %td
                gen age= (eventdate -  dateofbirth)/365.25
                Thanks again for your help!
                Cheers,
                Mariska

                Comment


                • #9
                  Thanks for the closure. The 365.25 definition is

                  1. Widely used
                  2. Easy to state
                  3. Close enough for most purposes

                  although it commits you to very minor absurdities such as

                  Code:
                   
                  . di (mdy(3,28,2014) - mdy(3,28,2013))/365.25
                  .99931554
                  personage was designed for calculations in which being exact about birthdays, or other key days, is needed. It would work with your daily date variables, but you evidently need something slightly different.

                  Comment


                  • #10
                    Hi Nick Cox . Thanks for your help. My search for answers brought me here. My latest problem is similar to this. How do I calculate age at test date using the age(). I have read the documentation from help age () but I still didn't get it.

                    Thanks.

                    Comment


                    • #11
                      Michael Olu Please don't post questions simultaneously in two or more threads. However, your post was helpful in that it lets me flag


                      personage (SSC) was superseded by the age functions added to Stata 16 in an update on 5 November 2020 and thus in turn to Stata 17. and later versions.

                      Comment

                      Working...
                      X