Report Design
 Crystal Reports Forum : Crystal Reports 9 through 2022 : Report Design
Message Icon Topic: Time Series Analysis Looking Back 30, 90, and 180 Post Reply Post New Topic
Author Message
apbeaulne
Newbie
Newbie
Avatar

Joined: 05 Dec 2007
Location: Canada
Online Status: Offline
Posts: 11
Quote apbeaulne Replybullet Topic: Time Series Analysis Looking Back 30, 90, and 180
     Posted: 19 Dec 2007 at 10:07am
In Health Care Knowing if someone is loosing weight is an important indicator of change in health status.
 
I need to be able to look at a series of dates within a given patient record (Chart Number) and determine if there was
 
a) 5% weight loss within a 30 day period
b) 7.5% weight loss within 90 day periord
c) 10% weight loss within a 180 day period
 
Every Date within the reporting period becomes the Reference Date
 
That is the
 
a) Reference Date - 30 Days
b) Reference Date - 90 Days
c) Reference Date - 180 Days
 
There is a twist.  Within any period there could be several dates on which a patient was weighed.
 
So one must pick the Maximum Weight within the period 30, 90, or 180 days and subtract the Reference weight.
 
Days Weight % Change 30 DAYS 90 Days 180 Days
Each 30 Days 5% Loss 7.5% Loss 10% Loss
177 January 1, 2007 -208 101 0.00
177 January 30, 2007 -179 100 -0.99   No No No
177 March 1, 2007 -149 95 -5.00   Yes No No
177 March 31, 2007 -119 92 -3.16   No Yes No
177 April 30, 2007 -89 92 0.00   No Yes No
177 May 30, 2007 -59 98 6.52   No No No
177 June 29, 2007 -29 92 -6.12   Yes No No
177 July 29, 2007 0 90 -2.17   No Yes Yes
 
For example On July 29 2007 the patient's weight was 90.
 
That was a 2.17% drop within 30 days, June 29 2007.
 
Even though April 30 is within the 90 days it is not the maximum weight but the weight on May 30 is the maximum and it is more than 7.5 % change so the 90 Days at 7.5 % is flag.
 
 
I would appreciate any help I can get with this.
 
In Summary is there a way to check if a date is within a certain number of days and then identify the Maximum Weight within the period and calculate the pecent change being greater than or equal to some value.
 
 
 
Paul
IP IP Logged
Lugh
Senior Member
Senior Member
Avatar

Joined: 14 Nov 2007
Online Status: Offline
Posts: 377
Quote Lugh Replybullet Posted: 21 Dec 2007 at 5:26am
Just to let you know, I'm trying to work out an answer that I know will work here.  I have some ideas, but I don't want to throw a bunch of half-baked stuff at you.  Hopefully I'll have something for you later today (the holidays are such a great time to play with questions like this!)...
IP IP Logged
Lugh
Senior Member
Senior Member
Avatar

Joined: 14 Nov 2007
Online Status: Offline
Posts: 377
Quote Lugh Replybullet Posted: 27 Dec 2007 at 6:31am
Sorry this took so long.  The holidays got in the way.  Plus, it was a tricky operation.  In the end, the only solution I could come up with was to brute force it.  Well, actually, you can do it using some tricky subqueries in your SQL command.  Which is probably the better method, all in all.  But, I was looking for a purely Crystal solution.

The basic approach I took was to create a pair of arrays (for effectively a 2-dimensional array) and store the date and weight of each record in it.  Then, run through a For loop to determine the maximum weight in each period.  The formula looks like:


Global DateTimeVar Array CumDate;
Global NumberVar Array CumWgt;

Local NumberVar CurMax := 0;
Local NumberVar iLoop;

Redim Preserve CumDate[RecordNumber];
Redim Preserve CumWgt[RecordNumber];

CumDate[RecordNumber] := {Weights_.WeighDate};
CumWgt[RecordNumber] := {Weights_.Weight};

If RecordNumber > 1 Then
    For iLoop := 1 to (RecordNumber - 1) Do
        (If CumDate[iLoop] > DateAdd("d",-31,{Weights_.WeighDate}) And CurMax < CumWgt[iLoop] Then
         CurMax := CumWgt[iLoop])
Else
    For iLoop := 1 to 1 Do
        (CurMax := {Weights_.Weight});

CurMax - {Weights_.Weight}


I'm hoping that most of that is fairly self-explanatory, once you step through it.  I can expand on it, if you like.

There are two caveats with this method.  First, arrays in Crystal are limited to 1000 members.  If you have a large number of records, you may run into this limitation.  The easiest solution is to add a step, in which, if UBound(CumDate) > 100 (why go all the way to 1000, when you know you don't need more than 90 days?), then run through a For..Do loop to set CumDate[iLoop] = CumDate[iLoop+1].  This effectively moves the whole array "window" through the records.

Second, you need to make sure you initialize your global variables in your report header.  My solution looked like:

Global DateTimeVar Array CumDate := MakeArray(DataDate);
Global NumberVar Array CumWgt := MakeArray(0);

CumDate[1]


Conveniently enough, this also returned the date the report was run.



There are a couple other notes.  First, you may notice that this formula only returns the amount of weight gained or lost.  I left the process of determining the percent lost and changing it to a Yes/No marker as an exercise for the reader.  Second, it is entirely possible to run this for fairly large reports with multiple patients.  Simply group the records by PatientID, and re-initialize your arrays in each group header.

Hope this helps.  I'd also be very curious as to whether anyone else was able to come up with a more elegant solution.

IP IP Logged
apbeaulne
Newbie
Newbie
Avatar

Joined: 05 Dec 2007
Location: Canada
Online Status: Offline
Posts: 11
Quote apbeaulne Replybullet Posted: 01 Jan 2008 at 12:53pm

I am just back from the Holidays.  I will try out the code you have provided.  Thank you so much for taking the time to do this.

Hopefully I will get back to you by January 3, 2008.
 
Paul
Paul
IP IP Logged
Printable version Printable version

Forum Jump
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot delete your posts in this forum
You cannot edit your posts in this forum
You cannot create polls in this forum
You cannot vote in polls in this forum