Copy link to clipboard
Copied
need a custom calculation script to calculate standard deviation from 8 Rows , this will be a .pdf form the input variable data points will be from users using this template as a form.
I can get the average from the simple calculation but struggling with the script for the standard deviation. Any help would be appreciated.
Header 1 | Header 2 | Header 3 | Header 4 | Header 5 | Header 6 | Header 7 | Header 8 | Header 9 | Header 11 |
---|---|---|---|---|---|---|---|---|---|
sample1Row1 | sample2Row1 | sample3Row1 | sample4Row1 | sample5Row1 | sample6Row1 | sample7Row1 | sample8Row1 | Average | stddeviation |
1 Correct answer
So the formula is not:
stddev = sqrt (sum (sampleXRow1 - average)^2 / (n-1))
But:
stddev = sqrt (sum ((sampleXRow1 - average)^2) / (n-1))
So the code should be something like this:
...var avg = Number(this.getField("AverageRow1").valueAsString);
var sum = 0;
var n = 0;
for (var i=1; i<=8; i++) {
var v = this.getField("sample"+i+"Row1").valueAsString;
if (v!="") {
sum+=Math.pow((Number(v)-avg),2);
n++;
}
}
if (n==0 || n==1) event.value = "";
else event.value = Math.sqrt(sum / (
Copy link to clipboard
Copied
What's the formula that you want to use?
Copy link to clipboard
Copied
stddev = sqrt (sum (sampleXRow1 - average)^2 / (n-1))
Copy link to clipboard
Copied
Not 100% sure about this code, but give it a try...
var avg = Number(this.getField("Average").valueAsString);
var sum = 0;
var n = 0;
for (var i=1; i<=8; i++) {
var v = this.getField("sample"+i+"Row1").valueAsString;
if (v!="") {
sum+=(Number(v)-avg);
n++;
}
}
if (n==0 || n==1) event.value = "";
else event.value = Math.sqrt(Math.pow(sum,2) / (n-1));
I assume that "n" stands for the number of (filled-in) fields.
I'm not sure how are you calculating the average, though, and if you're including empty fields in this calculation...
Edit: Syntax error fixed
Copy link to clipboard
Copied
am getting SyntaxError: unterminated string literal 5: at line 6
yes "n" stands for the number of "filled-in" fields.
average is calculated in the average field using the output of "Value is the " Average" in the Calculate option of the "Text filed properties"
Copy link to clipboard
Copied
Change line #5 to:
var v = this.getField("sample"+i+"Row1").valueAsString;
Regarding the Average field, you need to double-check how it works. I think that it includes empty fields as zero in the calculations, which might not be what you want.
Copy link to clipboard
Copied
This ran without any errors , however I am getting the output as "0"
Regarding Average field empty field taken as zero would be fine , because we a re running sample lab tests and all the fields will be mandatory for inputs, if it would be empty then "0" has to be assumed in that.
Copy link to clipboard
Copied
I'll need to see the actual file to help you further.
Copy link to clipboard
Copied
which file ? do you need me to send you anything ?
Copy link to clipboard
Copied
The actual PDF file. You can either send it to me directly (try6767 at gmail.com) or upload it to something like Dropbox and post a share link here on the forum.
Copy link to clipboard
Copied
Hi Try67,
Appreciate your assistance.
Attaching the file for your help.
Thanks in advance
Regards
Bossom Britto
+1-919-914-2620
Copy link to clipboard
Copied
Sent the .pdf to your email ID
Copy link to clipboard
Copied
Are you sure? It seems like you sent an email to the forum, instead...
Copy link to clipboard
Copied
Never mind, got it now...
The field names you provided were not accurate. Open the JS Console and you'll see an error message about the "Average" field.
The actual name seems to be "AverageRow1", so adjust it accordingly in the code.
Copy link to clipboard
Copied
I also think there's something wrong with your formula, because it seems to me that the sum of all the values minus the average will always be zero...
Copy link to clipboard
Copied
so if I take sample1Row1, sample2Row1,..... sample8Row1 = 1,2,3,4,5,6,7,8
the average would be 1+2+3+4+5+6+7+8 / 8 = 4.5
The desired output should be :
Stddev = sqrt {[summation [(x - 4.5)^2] / (8-1)} = sqrt { [sum [(1-4.5)^2 +.........+(8-4.5)^2] ] / (8-1)
= sqrt { [sum (12.25 + 6.25 + 2.25 + 0.25 + 0.25 +2.25 +6.25+12.25 )] / (8-1)}
= sqrt { 42/7}
= 6
Copy link to clipboard
Copied
So the formula is not:
stddev = sqrt (sum (sampleXRow1 - average)^2 / (n-1))
But:
stddev = sqrt (sum ((sampleXRow1 - average)^2) / (n-1))
So the code should be something like this:
var avg = Number(this.getField("AverageRow1").valueAsString);
var sum = 0;
var n = 0;
for (var i=1; i<=8; i++) {
var v = this.getField("sample"+i+"Row1").valueAsString;
if (v!="") {
sum+=Math.pow((Number(v)-avg),2);
n++;
}
}
if (n==0 || n==1) event.value = "";
else event.value = Math.sqrt(sum / (n-1));
Copy link to clipboard
Copied
You are excellent, thank you very much Try, that works !! you made my day.
Copy link to clipboard
Copied
Since this could be a fairly frequent type of calculation, I would create a document level function for this calculation. Even if you use just once in a form, you could copy the function to other forms as needed.
Calculating Standard Deviation with Array.map and Array.reduce, In JavaScript by Derick Bailey.
By putting all the values needed for the calculation one can use the "fitter" method" of the array object to remove any unwanted values like "null" or zeros if needed. The code also includes a function to compute the average.
Copy link to clipboard
Copied
Thanks gKaiseril,
I did go through this earlier but I do not have much knowledge of Java, so was not able to get this to map it to the way I had my form laid out.
Copy link to clipboard
Copied
First Acrobat uses JavaScript and not the Java computer language.
An array is a special type of object that represents a collection of items. It is very similar to an array in algebra. Use of the array allows one create a set of items for processing that might not be only from fields. It could also have constants inserted into the array. since the array can dynamically grow the number of elements that can be processed is not limited to just fixed number.
Again using a function to process the data and not the specific fields makes the calculation available to more than one field of file.
Here is a sample form Standard Deviation.
The custom calculation script for the Standard Deviation is:
var MyValues = new Array();
var MyFields = new Array("F1", "F2", "F3", "F4", "F5");
var oField;
var nField;
for(var i = 0; i < MyFields.length; i++)
{
nField = '';
nField = GetField(this, MyFields).valueAsString;
if(nField != "") MyValues.push(Number(nField));
}
event.value = standardDeviation(MyValues);
By inserting more field names to the "MyFields" array will increase the number of values to be included in the calculation.
I could also use the "filter" method of the array object to remove unwanted values and the script could then be written as:
var MyValues = new Array();
var MyFields = new Array("F1", "F2", "F3", "F4", "F5");
var oField;
var nField;
for(var i = 0; i < MyFields.length; i++)
{
nField = '';
nField = GetField(this, MyFields).valueAsString;
MyValues.push(Number(nField));
}
function RemoveNulls(element) {
return element.toString != null;
}
MyValues = MyValues.filter(RemoveNulls)
event.value = standardDeviation(MyValues);
If one looks through the other calculated fields, one will see I call other functions defined to assist in the standard deviation calculation.
Copy link to clipboard
Copied
@gkaiseril
I have followed your example, but I have two issue. I need to calculate the standard deviation of the sample not the population so how do I change the document JavaScript? Also, when I don't have any variation in my 10 values, I get a warning: JavaScript Window that says The value entered does not match the format of the field [StdDev4]
Here are the Document JavaScripts
Fields:
function GetField(oDoc, cField)
{
var oField = oDoc.getField(cField);
if(oField == null)
{
app.alert("Error accessing field \"" + cField + "\"!", 1, 0)
}
return oField;
}
StdDev:
function standardDeviation(values)
{
// compute the standard deviation from an array of vlaues;
// compute the average of the vaues;
var stdDev = "";
var avg = average(values);
if(avg != "")
{
// compute the squared difference of the values and the average;
var squareDiffs = values.map(function(value){
var diff = value - avg;
var sqrDiff = diff * diff;
return sqrDiff;
});
// average the squared differences;
var avgSquareDiff = average(squareDiffs);
stdDev = Math.sqrt(avgSquareDiff);
} // end avg not null;
return stdDev;
}
function average(data)
{
// compute the average of an array of values;
//sum the values in the array;
var sum = data.reduce(function(sum, value){
return sum + value;
}, 0);
// compute the average of the sum of the values if number of array elements is not 0;
var avg = '';
if(data.length > 0)
{
var avg = sum / data.length;
}
return avg;
}
function sum(value)
{
// sum an array of values;
var Sum = value.reduce(function(Sum, value){
return Sum + value;
}, 0);
return Sum;
}
Custom Calculation Script:
var MyValues = new Array();
var MyFields = new Array("AdjustedResult5.1", "AdjustedResult5.2","AdjustedResult5.3", "AdjustedResult5.4", "AdjustedResult5.5", "AdjustedResult5.6", "AdjustedResult5.7", "AdjustedResult5.8", "AdjustedResult5.9", "AdjustedResult5.10" );
var oField;
var nField;
for(var i = 0; i < MyFields.length; i++)
{
nField = '';
nField = GetField(this, MyFields).valueAsString;
if(nField != "") MyValues.push(Number(nField));
}
event.value = standardDeviation(MyValues);
Copy link to clipboard
Copied
I have also tried this for the standard deviation of the sample:
var Ravg = Number(this.getField("AvgAdjResult.1.0").valueAsString);
var Rsum = 0;
var Rn = 0;
for (var i=1; i<=10; i++) {
var Rv = this.getField("AdjustedResult1."+i).valueAsString;
if (Rv!="") {
Rsum+=Math.pow((Number(Rv)-Ravg),2);
Rn++;
}
}
if (Rn==0 || Rn==1) event.value = "";
else event.value = Math.sqrt(Rsum / (Rn-1));
However, I want the cell to stay blank unless there is an average calculated. Also we have low variability in our 10 replicates so the standard deviation can be zero, but I get the error mentioned above: The value entered does not match the format of the field [StdDev4] because it doesn't like to take the square root of zero. How do I make this error disappear, but the cell still have a numeric value of 0.000000?
I tried changing it to this:
var Ravg = Number(this.getField("AvgAdjResult.1.0").valueAsString);
var Rsum = 0;
var Rn = 0;
for (var i=1; i<=10; i++) {
var Rv = this.getField("AdjustedResult1."+i).valueAsString;
if (Rv!="") {
Rsum+=Math.pow((Number(Rv)-Ravg),2);
Rn++;
}
}
var b = +getField("Result1.10").value;
var c = Rsum / (Rn-1);
if (b==0) event.value = "";
else if (c==0) event.value = 0.000000;
else event.value = Math.sqrt (c);
but then I don't get a result at all.
Field names are shown in bold below and an example of the data is below as well
Barometric Pressure (mm/Hg) | Result 1 | Result 2 | Result 3 | Result 4 | Result 5 | Result 6 | Result 7 | Result 8 | Result 9 | Result 10 | Average of Adjusted Results | Standard Deviationof Adj Results | %RSD for dry gas standard | Standard Uncertainty | Expanded Uncertainty 99%, k=3.25 | UoM g/210L | |
mmHg | Actual | Result1.1 | Result1.2 | Result1.3 | Result1.4 | Result1.5 | Result1.6 | Result1.7 | Result1.8 | Result1.9 | Result1.10 | AvgAdjResult.1.0 | StdDev1 | RSD1 | StdUnc1 | ExpUnc1 | UoM1 |
Adjusted* | AdjustedResult1.1 | AdjustedResult1.2 | AdjustedResult1.3 | AdjustedResult1.4 | AdjustedResult1.5 | AdjustedResult1.6 | AdjustedResult1.7 | AdjustedResult1.8 | AdjustedResult1.9 | AdjustedResult1.10 |
Barometric Pressure (mm/Hg) | Result 1 | Result 2 | Result 3 | Result 4 | Result 5 | Result 6 | Result 7 | Result 8 | Result 9 | Result 10 | Average of Adjusted Results | Standard Deviation of Adj Results | %RSD for dry gas standard | Standard Uncertainty | Expanded Uncertainty 99%, k=3.25 | UoM g/210L | |
752 | Actual | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.000000 | 0.000000 | 0.000000 | 3.447146 | 0.001 |
Adjusted* | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 | |||||||
752 | Actual | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.000000 | 0.000000 | 0.000000 | 3.447146 | 0.001 |
Adjusted* | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | 0.036 | |||||||
752 | Actual | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.081 | 0.000000 | 0.000000 | 0.000000 | 3.447146 | 0.003 |
Adjusted* | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | 0.082 | |||||||
752 | Actual | 0.148 | 0.149 | 0.149 | 0.149 | 0.148 | 0.148 | 0.148 | 0.148 | 0.148 | 0.148 | 0.149 | 0.000488 | 0.327641 | 0.036405 | 3.449175 | 0.005 |
Adjusted* | 0.150 | 0.151 | 0.151 | 0.151 | 0.150 | 0.150 | 0.150 | 0.150 | 0.150 | 0.150 | |||||||
752 | Actual | 0.297 | 0.297 | 0.297 | 0.297 | 0.297 | 0.297 | 0.296 | 0.296 | 0.296 | 0.296 | 0.299 | 0.000522 | 0.174546 | 0.019394 | 3.447722 | 0.010 |
Adjusted* | 0.300 | 0.300 | 0.300 | 0.300 | 0.300 | 0.300 | 0.299 | 0.299 | 0.299 | 0.299 |

