
|
computing chronological age
Hi there, I would greatly appreciate some assistance to compute chronological age using SPSS/PASW. I need the output variable to represent (e.g) a chronological age of 12 years, 6 months and 27 days as 12:6:27 (or 12:06:27).
The data is set up as Int_Date Child_DOB Child_Age 25-Aug-08 31-Jul-06 yy:mm:dd 25-Aug-08 15-Dec-04 yy:mm:dd 11-Aug-08 6-Jul-05 yy:mm:dd 6-Aug-08 2-Sep-06 yy:mm:dd 5-Aug-08 22-Feb-06 yy:mm:dd
4-Aug-08 23-Feb-06 yy:mm:dd 8-Sep-08 31-Jul-04 yy:mm:dd I have looked in help and searched, but I can only find instances where SPSS/PASW formats the date as an untruncated decimal or as individual units.
For reference, I need syntax to represent the results of something like this calculator: http://www.lewisandlewis.com.au/maccalc.html only for the output to be formatted as above.
Thankyou in advance Christine
|

|
Re: computing chronological age
Hi Christine,
I think the following syntax (and test data) will produce the output you
want. You can modify it a bit if needed.
It's a bit long winded - no doubt it can be done more succinctly!
Clive
***************
DATA LIST FREE/
int_date (DATE9) dob(DATE9).
BEGIN DATA
25-aug-08 31-jul-06
25-aug-08 15-dec-04
11-aug-08 06-jul-05
06-aug-08 02-sep-06
05-aug-08 22-feb-06
04-aug-08 23-feb-06
08-sep-08 31-jul-04
END DATA.
LIST.
* Date and Time Wizard: age.
COMPUTE age=(int_date - dob) / time.days(1).
VARIABLE LABEL age.
VARIABLE LEVEL age (SCALE).
FORMATS age (F8.2).
VARIABLE WIDTH age(8).
EXECUTE.
COMPUTE years=age/365.25.
EXECUTE.
COMPUTE wholeYrs=TRUNC(years).
EXECUTE.
COMPUTE Mnths=12*(years-wholeYrs).
EXECUTE.
COMPUTE wholeMnths=TRUNC(Mnths).
EXECUTE.
COMPUTE days=TRUNC(30.42*(Mnths-wholeMnths)).
EXECUTE.
EXE.
STRING ageStr (A9).
COMPUTE ageStr=
CONCAT(STRING(wholeYrs,N3), ":", STRING(wholeMnths, N2), ":", STRING
(days, N2)).
EXE.
=====================
To manage your subscription to SPSSX-L, send a message to
LISTSERV@... (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
|

|
Re: computing chronological age
At 10:13 PM 10/28/2009, Christine wrote:
I would greatly appreciate some
assistance to compute chronological age using SPSS/PASW. I need the
output variable to represent (e.g) a chronological age of 12 years, 6
months and 27 days as 12:6:27 (or 12:06:27).
I assume you want the standard definition of that, using calendar years
and calendar months. If so, the calculation isn't quite straightforward,
since neither calendar years nor calendar months have fixed
length.
Try this as a solution. The result has to be a character string, because
(as stated above), it truly isn't a number.
I'd normally make YD1, MD1, and DD1 scratch variables, but listing them
may clarify the logic. I have a feeling I should be using DATEDIFF, but
using XDATE functions seems to make the 'borrowing' easier.
And, this is tricky logic. Please, all, inspect it, and post corrections
or improvements that you see.
|-----------------------------|---------------------------|
|Output
Created
|29-OCT-2009 19:20:19 |
|-----------------------------|---------------------------|
Int_Date Child_DOB
25-AUG-2008 31-JUL-2006
25-AUG-2008 15-DEC-2004
11-AUG-2008 06-JUL-2005
06-AUG-2008 02-SEP-2006
05-AUG-2008 22-FEB-2006
04-AUG-2008 23-FEB-2006
08-SEP-2008 31-JUL-2004
08-SEP-2008 09-SEP-2004
Number of cases read: 8 Number of cases
listed: 8
NUMERIC YD1 MD1 DD1 YD2 MD2 DD2 (F3).
* Compute the straightforward Y-M-D differences:
... .
COMPUTE YD1 = XDATE.YEAR (Int_DAte) - XDATE.YEAR (Child_DOB).
COMPUTE MD1 = XDATE.MONTH(Int_Date) - XDATE.MONTH(Child_DOB).
COMPUTE DD1 = XDATE.MDAY (Int_Date) - XDATE.MDAY (Child_DOB).
* Correct the Y-M-D differences,
eliminating ... .
* negative values by
'borrowing':
... .
* --- Borrow days, taking the month borrowed as
--- .
* --- having 30
days.
--- .
* That seems to be
what
.
*
http://www.lewisandlewis.com.au/maccalc.html
.
* does, though one could also use the
actual .
* number of days in the borrowed
month.
.
DO IF DD1 GE 0.
. COMPUTE DD2 = DD1.
. COMPUTE MD2 = MD1.
ELSE.
. COMPUTE DD2 = DD1 + 30.
. COMPUTE MD2 = MD1 - 1.
END IF.
* --- Borrow months, from 12-month
years. ---
.
* Apply the correction to the
months-difference .
* calculated above, possibly corrected from
the .
* the straightforward
value.
.
DO IF MD2 GE 0.
. COMPUTE YD2 = YD1.
. COMPUTE MD2 = MD2.
ELSE.
. COMPUTE YD2 = YD1 - 1.
. COMPUTE MD2 = MD2 + 12.
END IF.
* Combine the corrected differences as a single
... .
* character
string
... .
STRING Child_Age (A8).
COMPUTE Child_Age = CONCAT(STRING(YD2,F2),':',
STRING(MD2,N2),':',
STRING(DD2,N2) ).
LIST.
List
|-----------------------------|---------------------------|
|Output
Created
|29-OCT-2009 19:20:20 |
|-----------------------------|---------------------------|
Int_Date Child_DOB YD1 MD1 DD1 YD2 MD2 DD2
Child_Age
25-AUG-2008 31-JUL-2006 2 1 -6
2 0 24 2:00:24
25-AUG-2008 15-DEC-2004 4 -4 10
3 8 10 3:08:10
11-AUG-2008 06-JUL-2005 3 1
5 3 1 5 3:01:05
06-AUG-2008 02-SEP-2006 2 -1 4
1 11 4 1:11:04
05-AUG-2008 22-FEB-2006 2 6 -17
2 5 13 2:05:13
04-AUG-2008 23-FEB-2006 2 6 -19
2 5 11 2:05:11
08-SEP-2008 31-JUL-2004 4 2 -23
4 1 7 4:01:07
08-SEP-2008 09-SEP-2004 4 0 -1
3 11 29 3:11:29
Number of cases read: 8 Number of cases
listed: 8
=============================
APPENDIX: Test data, and code
=============================
DATA LIST LIST/
Int_Date Child_DOB
(DATE11 DATE11).
BEGIN DATA
25-Aug-08 31-Jul-06
25-Aug-08 15-Dec-04
11-Aug-08 6-Jul-05
6-Aug-08 2-Sep-06
5-Aug-08 22-Feb-06
4-Aug-08 23-Feb-06
8-Sep-08 31-Jul-04
8-Sep-08 9-Sep-04
END DATA.
LIST.
NUMERIC YD1 MD1 DD1 YD2 MD2 DD2 (F3).
* Compute the straightforward Y-M-D differences:
... .
COMPUTE YD1 = XDATE.YEAR (Int_DAte) - XDATE.YEAR (Child_DOB).
COMPUTE MD1 = XDATE.MONTH(Int_Date) - XDATE.MONTH(Child_DOB).
COMPUTE DD1 = XDATE.MDAY (Int_Date) - XDATE.MDAY (Child_DOB).
* Correct the Y-M-D differences,
eliminating ... .
* negative values by
'borrowing':
... .
* --- Borrow days, taking the month borrowed as
--- .
* --- having 30
days.
--- .
* That seems to be
what
.
*
http://www.lewisandlewis.com.au/maccalc.html
.
* does, though one could also use the
actual .
* number of days in the borrowed
month.
.
DO IF DD1 GE 0.
. COMPUTE DD2 = DD1.
. COMPUTE MD2 = MD1.
ELSE.
. COMPUTE DD2 = DD1 + 30.
. COMPUTE MD2 = MD1 - 1.
END IF.
* --- Borrow months, from 12-month
years. ---
.
* Apply the correction to the
months-difference .
* calculated above, possibly corrected from
the .
* the straightforward
value.
.
DO IF MD2 GE 0.
. COMPUTE YD2 = YD1.
. COMPUTE MD2 = MD2.
ELSE.
. COMPUTE YD2 = YD1 - 1.
. COMPUTE MD2 = MD2 + 12.
END IF.
* Combine the corrected differences as a single
... .
* character
string
... .
STRING Child_Age (A8).
COMPUTE Child_Age = CONCAT(STRING(YD2,F2),':',
STRING(MD2,N2),':',
STRING(DD2,N2) ).
LIST.
=====================
To manage your subscription to SPSSX-L, send a message to
LISTSERV@... (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
|

|
Re: computing chronological age
At 08:02 PM 10/29/2009, Jon K Peck wrote, off-list:
The datediff function calculates
exact, calendar-aware intervals in whatever units are requested.
Indeed, DATEDIFF does that, and I thought it should be the tool the tool
to use. It makes calculating the years and the months much
easier:
COMPUTE YD1 =
DATEDIFF(Int_Date,Child_DOB,"Years").
COMPUTE MD1 = DATEDIFF(Int_Date,Child_DOB,"Months").
/TIME.DAYS(1).
COMPUTE YD2 = YD1.
COMPUTE MD2 = MOD(MD1,12).
But I can't see how to get the right 'days' value. The code below
has a couple of attempts, that don't work at all.
Help, anyone?
=============================
APPENDIX: Test data, and code
=============================
NOT WORKING: the 'days' values are computed wrong, or not at all
DATA LIST LIST/
Int_Date Child_DOB
(DATE11 DATE11).
BEGIN DATA
25-Aug-08 31-Jul-06
25-Aug-08 15-Dec-04
11-Aug-08 6-Jul-05
6-Aug-08 2-Sep-06
5-Aug-08 22-Feb-06
4-Aug-08 23-Feb-06
8-Sep-08 31-Jul-04
8-Sep-08 9-Sep-04
END DATA.
LIST.
NUMERIC YD1 MD1 DD1 DD1A YD2 MD2
DD2 DD2A (F3).
FORMATS DD1 DD1A DD2
DD2A
(F5).
COMPUTE YD1 = DATEDIFF(Int_Date,Child_DOB,"Years").
COMPUTE MD1 = DATEDIFF(Int_Date,Child_DOB,"Months").
COMPUTE DD1 = DATEDIFF(Int_Date,Child_DOB,"Days").
COMPUTE DD1A = MOD (Int_Date -
Child_DOB,TIME.DAYS(1))
/TIME.DAYS(1).
COMPUTE YD2 = YD1.
COMPUTE MD2 = MOD(MD1,12).
COMPUTE DD2 = MOD(DD1,30).
LIST.
=====================
To manage your subscription to SPSSX-L, send a message to
LISTSERV@... (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
|

|
Re: computing chronological age
Hello Richard,
Thanks for this - it looks like my suggested solution was a bit too
simplistic!
Regards
Clive
=====================
To manage your subscription to SPSSX-L, send a message to
LISTSERV@... (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
|

|
Re: computing chronological age
Here's how to get the days correct.
checkcalc below shows that the parts do add up to the later date.
Regards,
Jon
BEGIN DATA
25-Aug-08 31-Jul-06
25-Aug-08 15-Dec-04
11-Aug-08 6-Jul-05
6-Aug-08 2-Sep-06
5-Aug-08 22-Feb-06
4-Aug-08 23-Feb-06
8-Sep-08 31-Jul-04
8-Sep-08 9-Sep-04
END DATA.
COMPUTE YD1 = DATEDIFF(Int_Date,Child_DOB,"Years").
COMPUTE MD1 = DATEDIFF(Int_Date,Child_DOB,"Months").
compute part1 = datesum(child_dob, yd1,
"years").
compute monthsremaining = datediff(int_date,
part1, "months").
compute part2 = datesum(part1, monthsremaining,
"months").
compute days = datediff(int_date, part2,
"days").
compute checkcalc = datesum(part2, days,
"days").
format part1 part2 checkcalc(adate12).
| From:
| Richard Ristow <wrristow@...>
|
| To:
| SPSSX-L@...
|
| Date:
| 10/30/2009 12:02 AM
|
| Subject:
| Re: [SPSSX-L] computing chronological
age
|
| Sent by:
| "SPSSX(r) Discussion" <SPSSX-L@...> |
At 08:02 PM 10/29/2009, Jon K Peck wrote, off-list:
The datediff function calculates exact, calendar-aware
intervals in whatever units are requested.
Indeed, DATEDIFF does that, and I thought it should be the tool the tool
to use. It makes calculating the years and the months much easier:
COMPUTE YD1 = DATEDIFF(Int_Date,Child_DOB,"Years").
COMPUTE MD1 = DATEDIFF(Int_Date,Child_DOB,"Months").
/TIME.DAYS(1).
COMPUTE YD2 = YD1.
COMPUTE MD2 = MOD(MD1,12).
But I can't see how to get the right 'days' value. The code below has a
couple of attempts, that don't work at all.
Help, anyone?
=============================
APPENDIX: Test data, and code
=============================
NOT WORKING: the 'days' values are computed wrong, or not at all
DATA LIST LIST/
Int_Date Child_DOB
(DATE11 DATE11).
BEGIN DATA
25-Aug-08 31-Jul-06
25-Aug-08 15-Dec-04
11-Aug-08 6-Jul-05
6-Aug-08 2-Sep-06
5-Aug-08 22-Feb-06
4-Aug-08 23-Feb-06
8-Sep-08 31-Jul-04
8-Sep-08 9-Sep-04
END DATA.
LIST.
NUMERIC YD1 MD1 DD1 DD1A YD2 MD2 DD2
DD2A (F3).
FORMATS DD1 DD1A DD2 DD2A
(F5).
COMPUTE YD1 = DATEDIFF(Int_Date,Child_DOB,"Years").
COMPUTE MD1 = DATEDIFF(Int_Date,Child_DOB,"Months").
COMPUTE DD1 = DATEDIFF(Int_Date,Child_DOB,"Days").
COMPUTE DD1A = MOD (Int_Date - Child_DOB,TIME.DAYS(1))
/TIME.DAYS(1).
COMPUTE YD2 = YD1.
COMPUTE MD2 = MOD(MD1,12).
COMPUTE DD2 = MOD(DD1,30).
LIST.
===================== To manage your subscription
to SPSSX-L, send a message to LISTSERV@... (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
|

|
Re: computing chronological age
At 09:31 AM 10/30/2009, Jon K Peck wrote:
Here's how to get the days
correct. checkcalc below shows that the parts do add up to the
later date.
Thank you! That is a very nice approach (and much simpler code):
. take the difference in years, then 'advance' the DOB by that amount;
. take the difference in months from that advanced date, and advance
again by that amount; and then
. take the difference in days from the twice-advanced date.
Below is the listing from a run with Jon's code.
Here's a comparison of the results, stitched together from the output
below and what I posted yesterday. YrDif, MonDif and DayDif are
calculated using Jon's logic; YD1 thru DD2 are the differences I
calculated.
Int_Date Child_DOB YrDif
MonDif AdvYrMn DayDif YD1 MD1 DD1 YD2 MD2
DD2
25-AUG-2008 31-JUL-2006
2 0
31-JUL-2008 25 2 1
-6 2 0 24
25-AUG-2008 15-DEC-2004
3 8
15-AUG-2008 10 4 -4
10 3 8 10
11-AUG-2008 06-JUL-2005
3 1
06-AUG-2008 5 3
1 5 3 1 5
06-AUG-2008 02-SEP-2006 1
11 02-AUG-2008 4 2
-1 4 1 11 4
05-AUG-2008 22-FEB-2006
2 5
22-JUL-2008 14 2 6
-17 2 5 13
04-AUG-2008 23-FEB-2006
2 5
23-JUL-2008 12 2 6
-19 2 5 11
08-SEP-2008 31-JUL-2004
4 1
31-AUG-2008 8 4 2
-23 4 1 7
08-SEP-2008 09-SEP-2004 3
11 09-AUG-2008 30 4
0 -1 3 11 29
Where the interview day-of-month number is less than the
DOB day-of-month number, my final 'days' difference (DD2) is 1 less than
Jon's (DayDif). That's from my taking months as having 30 days, following
the on-line calculator recommended; the months actually 'borrowed' from
all have 31 days. Jon's is definitely the recommended value.
Demonstration run, using Jon's logic:
|-----------------------------|---------------------------|
|Output
Created
|30-OCT-2009 10:38:10 |
|-----------------------------|---------------------------|
Int_Date Child_DOB
25-AUG-2008 31-JUL-2006
25-AUG-2008 15-DEC-2004
11-AUG-2008 06-JUL-2005
06-AUG-2008 02-SEP-2006
05-AUG-2008 22-FEB-2006
04-AUG-2008 23-FEB-2006
08-SEP-2008 31-JUL-2004
08-SEP-2008 09-SEP-2004
Number of cases read: 8 Number of cases
listed: 8
NUMERIC YrDif (F3)
AdvYrs (DATE11)
MonDif
(F3) AdvYrMn (DATE11)
DayDif
(F3) checkcalc (DATE11).
COMPUTE YrDif =
DATEDIFF(Int_Date,Child_DOB,"Years").
compute AdvYrs = datesum (child_dob, YrDif,
"years").
compute MonDif = datediff(int_date, AdvYrs,
"months").
compute AdvYrMn = datesum (AdvYrs, MonDif,
"months").
compute DayDif = datediff(int_date,
AdvYrMn,"days").
compute checkcalc = datesum (AdvYrMn, DayDif,
"days").
LIST.
|-----------------------------|---------------------------|
|Output
Created
|30-OCT-2009 10:38:11 |
|-----------------------------|---------------------------|
Int_Date Child_DOB
YrDif AdvYrs MonDif
AdvYrMn DayDif checkcalc
25-AUG-2008 31-JUL-2006 2
31-JUL-2008 0 31-JUL-2008
25 25-AUG-2008
25-AUG-2008 15-DEC-2004 3
15-DEC-2007 8 15-AUG-2008
10 25-AUG-2008
11-AUG-2008 06-JUL-2005 3
06-JUL-2008 1
06-AUG-2008 5 11-AUG-2008
06-AUG-2008 02-SEP-2006 1
02-SEP-2007 11
02-AUG-2008 4 06-AUG-2008
05-AUG-2008 22-FEB-2006 2
22-FEB-2008 5 22-JUL-2008
14 05-AUG-2008
04-AUG-2008 23-FEB-2006 2
23-FEB-2008 5 23-JUL-2008
12 04-AUG-2008
08-SEP-2008 31-JUL-2004 4
31-JUL-2008 1
31-AUG-2008 8 08-SEP-2008
08-SEP-2008 09-SEP-2004 3
09-SEP-2007 11 09-AUG-2008
30 08-SEP-2008
Number of cases read: 8 Number of cases
listed: 8
=============================
APPENDIX: Test data, and code
=============================
DATA LIST LIST/
Int_Date Child_DOB
(DATE11 DATE11).
BEGIN DATA
25-Aug-08 31-Jul-06
25-Aug-08 15-Dec-04
11-Aug-08 6-Jul-05
6-Aug-08 2-Sep-06
5-Aug-08 22-Feb-06
4-Aug-08 23-Feb-06
8-Sep-08 31-Jul-04
8-Sep-08 9-Sep-04
END DATA.
LIST.
NUMERIC YrDif (F3)
AdvYrs (DATE11)
MonDif
(F3) AdvYrMn (DATE11)
DayDif
(F3) checkcalc (DATE11).
COMPUTE YrDif =
DATEDIFF(Int_Date,Child_DOB,"Years").
compute AdvYrs = datesum (child_dob, YrDif,
"years").
compute MonDif = datediff(int_date, AdvYrs,
"months").
compute AdvYrMn = datesum (AdvYrs, MonDif,
"months").
compute DayDif = datediff(int_date,
AdvYrMn,"days").
compute checkcalc = datesum (AdvYrMn, DayDif,
"days").
LIST.
=====================
To manage your subscription to SPSSX-L, send a message to
LISTSERV@... (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
|