|
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 |
|
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 [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 |
|
In reply to this post by Christine-28
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 [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 |
|
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 [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 |
|
In reply to this post by Christine-28
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 [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 |
|
In reply to this post by Richard Ristow
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).
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 [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 |
|
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 [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 |
| Free forum by Nabble | Edit this page |
