ColdFusion TIPS PLUS
Issue 00090 http://www.cftipsplus.com
I. My CommentsII. ColdFusion In Context: T-Value
By R. Martin Ladner
martin.ladner@knology.net
Books For Sale
http://nsnd.vstorelibrary.com/
I. Comments:
I am having fun... my internet connection is down at home. Send in your Complaints about hosts you have had trouble with and send in Compliments about others who have done a good job.
Thanks and Keep Coding,
Nathan Stanford
President/CEO
http://www.cftipsplus.com
http://www.htmlostips.com
If you have suggestions for articles send them to us.
If you would like to write for cftipsplus.com
send us an email to:
admin@cftipsplus.com
IF YOU WANT TO BE AN AUTHOR SEND IN YOUR COLDFUSION TIPS.
Remember this is a great way to get your name known in the
ColdFusion Community.
If you have any suggestions please email me at
cftips@nsnd.com.
II. ColdFusion in Context: T-Value
By R. Martin Ladner
martin.ladner@knology.net
Suppose you have to evaluate the difference between the before-treatment scores and the after-treatment scores for subjects of an experimental treatment. The following procedure lets you enter values, compute the difference in scores for each subject, and calculate the t-value which can be used to determine the likelihood that the difference could have occurred by chance. There are many different ways to calculate a t-value. This is one way. During this demonstration, you'll manipulate data entering and leaving a textarea field, work with an array, use ColdFusion's square root function, and implement a complex algorithm in ColdFusion.
Overview
Everything will take place on a single page: tvalue.cfm. The page must initialize its own variables. The bulk of it will be a form whose textarea fields are shaped into tall, thin columns and whose surroundings are formatted with table cells. The user will enter data into the first two columns and then click the calculate button. This will cause the page to be reloaded with the data, only this time the remaining columns and the bottom of the page will contain calculations based on the data.
Initialize and Begin the Form
Give a short explanation and set form field defaults: one for each column.
Basis for t-value Derived from Pre- and Post-Treatment Measurements.
<cfparam name="form.Pretreat" default="">
<cfparam name="form.Posttreat" default="">
<cfparam name="form.Diff" default="">
<cfparam name="form.DiffSquared" default="">
Name the form and open up the table it contains.
<form name="Scores" action="Tvalue.cfm" method="post">
<table border=1>
<tr><td>PRE-<br>
TREATMENT<br></td>
<td>POST-<br>
TREATMENT</td><td>DIFFERENCE<br>
IN SCORES</td>
<td>DIFFERENCE<br>
SQUARED</td>
</tr>
Accept and Analyze the Pre-Treatment Column
The only work that needs to be done directly to this column is to accept, store, and count its values. The physical attribute preserves line feeds. The array stores the data, one row at a time. The list treats the space, newline, and carriage return characters as delimiters. It treats consecutive delimters as one and the data in between as items in the list. If the val function encounters something it can't interpret as a number, it converts it to zero. Element 1 of the array receives the first value, element 2 receives the second value, and so forth. The next paragraph will have a value just below it; so, a paragraph mark is used here to align this column with the next.
<tr>
<td>
<textarea name="Pretreat" wrap="physical" rows="25" cols="3">
<cfoutput>#trim(form.Pretreat)#</cfoutput></textarea>
<cfset PrePoints=ArrayNew(1)>
<cfset PreCount=0>
<cfloop list="#form.Pretreat#" index="Value"
delimiters=" #chr(10)##chr(13)#">
<cfset PreCount=PreCount+1>
<cfset PrePoints[PreCount]=val(Value)>
</cfloop>
<p>
</td>
Accept and Analyze the Post-Treatment Column
This code begins in the same manner as the previous code. Each item in the column is stored and counted. However, the count is displayed just below the column. N represents the number of measurements.
<td>
<textarea name="Posttreat" wrap="physical" rows="25" cols="3">
<cfoutput>#trim(form.Posttreat)#</cfoutput></textarea>
<cfset PostPoints=ArrayNew(1)>
<cfset PostCount=0>
<cfloop list="#form.Posttreat#" index="Value"
delimiters=" #chr(10)##chr(13)#">
<cfset PostCount=PostCount+1>
<cfset PostPoints[PostCount]=val(Value)>
</cfloop>
<br>N=<cfoutput>#PostCount#</cfoutput>
</td>
This particular procedure requires that each subject be measured twice. Therefore, the number of entries for the first column must match the number of entries for the second.
<cfif PreCount neq PostCount>
Cannot proceed until the Pre and Post columns have the same number of values.
<cfabort>
</cfif>
Measure, Store, and Display the Difference Column
Determine and store the difference in the following manner. Loop through the pre and post arrays, storing the difference between their first element into the first element of a separate array. Repeat for subsequent elements until all have been used. As each item is stored, add it to a linefeed-separated list: the field for the difference column in the form. Accumulate the total, then display it below the column.
<cfset DiffSum=0>
<cfset DiffPoints=ArrayNew(1)>
<cfset form.Diff="">
<cfloop from="1" to="#PostCount#" index="Point">
<cfset DiffPoints[Point]=PostPoints[Point]-PrePoints[Point]>
<cfset form.Diff=listAppend(form.Diff,DiffPoints[Point],"#chr(10)#")>
<cfset DiffSum=DiffSum+DiffPoints[Point]>
</cfloop>
<td>
<textarea name="Diff" wrap="physical" rows="25" cols="4">
<cfoutput>#trim(form.Diff)#</cfoutput></textarea><br>
<cfoutput>Sum=#DiffSum#</cfoutput>
</td>
Calculate, Store, and Display the Difference Squared Column
Determine and store the difference squared in the following manner. Loop through the difference array, multiplying each element by itself, appending it to a linefeed-separated list for display and accumulating the total of these squares. Display the total below the column. Close the table
<cfset DiffSquaredSum=0>
<cfset form.DiffSquared="">
<cfloop from="1" to="#PostCount#" index="Point">
<cfset Squared=DiffPoints[Point]*DiffPoints[Point]>
<cfset form.DiffSquared=listAppend(form.DiffSquared,Squared,"#chr(10)#")>
<cfset DiffSquaredSum=DiffSquaredSum+Squared>
</cfloop>
<td>
<textarea name="DiffSquared" wrap="physical" rows="25" cols="6">
<cfoutput>#trim(form.DiffSquared)#</cfoutput></textarea><br>
<cfoutput>Sum=#DiffSquaredSum#</cfoutput>
</td>
</tr>
</table>
<input type="reset" name="Oops" value="Reset">
<input type="submit" name="Doit" value="Calculate">
</form>
Perform and Display Remaining Calculations
Because there will division by one less than the number of measurements, stop if at least two measurements have not been entered.
<cfif PostCount lt 2>
Further calculations cannot take place until at least two sets of scores have been entered.
<cfabort>
</cfif>
Now prepare for the various steps. Some of this could have been handled by using the val function within cfoutput tags, but the details are clearer to the programmer this way. The only unfamiliar function (taken by itself) is ColdFusion's square root function: Sqr. The html ordered list (ol) tag is used here to organize the display. It generates the step numbers itself.
<cfset SquaredDiffSum=DiffSum*DiffSum>
<cfset Step1=PostCount*DiffSquaredSum>
<cfset Step2=Step1-SquaredDiffSum>
<cfset DegOfFreedom=PostCount-1>
<cfset Step3=Step2/DegOfFreedom>
<cfset Step4=Sqr(Step3)>
<cfset Traw=DiffSum/Step4>
<cfset Tround=round(Traw*10000)/10000>
<h4>Procedure to find "t"</h4>
<ol>
<li>Multiply the number of scores
(<cfoutput>#PostCount#</cfoutput>)
by the square of the differences
(<cfoutput>#DiffSquaredSum#)
(yielding #Step1#</cfoutput>).
<li>Take the sum of the differences
(<cfoutput>#DiffSum#</cfoutput>),
square it (<cfoutput>#SquaredDiffSum#</cfoutput>),
and subtract it from step 1
(leaving <cfoutput>#Step2#</cfoutput>).
<li>Take the number of scores
(<cfoutput>#PostCount#</cfoutput>),
subtract one from it to find the degrees of freedom,
and divide the result (<cfoutput>#DegOfFreedom#</cfoutput>)
into Step 2 (yielding <cfoutput>#Step3#</cfoutput>).
<li>Obtain the square root of Step 3
(yielding <cfoutput>#Step4#</cfoutput>).
<li>Divide Step 4 into the sum of the differences
(<cfoutput>#DiffSum# yielding #Traw#</cfoutput>
which to four decimal places rounds to
<cfoutput>#Tround#</cfoutput>).
</ol>
Now What?
Large samples assume a normal distribution. The demonstrated procedure, however, assumes that the distribution is slightly flatter than that. For a small sample, a larger proportion of the scores will lie farther from the mean than for a normal distribution. Take the t-value and look it up in a table of such values to determine the likelihood that the difference in measurements before and after treatment is due to chance.
If you're feeling brave, extend the technique to replace the table of t-values altogether.
=Marty=
Publisher and Creator:
Nathan Stanford,
admin@cftipsplus.comBooks For Sale
http://nsnd.vstorelibrary.com/
http://www.cftipsplus.com
Macromedia and ColdFusion are U.S. registered trademarks.
Copyright (c) 2000 - 2002
CFTIPSPLUS.COM and NSND.COM
Permission is granted to circulate this publication via
MANUAL forwarding by email to friends provided that the text is
forwarded in its entirety and no fee is charged.