# Average Multiple Signals

## Recommended Posts

• Seeq Team

We often get asked how to create an average of multiple signals, particularly when not all signals are always valid across the desired time range.

The Seeq Knowledge Base article "Find Min, Max, and Average from Multiple Signals" describes the way to perform this calculation if the signals are all valid. In this case, an average between signals a through d would be:

`(\$a + \$b + \$c + \$d)/4`

However, when one of the signals is not valid, the number of signals drops to 3, but the denominator does not change with this formula.

In order to allow your denominator to change with the number of valid signals, it requires the denominator to be changed to a formula that counts the number of valid signals. One way to count the number of valid signals is to use the following equation (works for R21.0.41 or later):

```\$Zero = 0.tosignal(1min) // creates a scalar value of 0 to splice in when the values are invalid
\$a.toboolean().sign().splice(\$Zero,\$a.tocapsules().inverse())+\$b.toboolean().sign().splice(\$Zero,\$b.tocapsules().inverse())+\$c.toboolean().sign().splice(\$Zero,\$c.tocapsules().inverse())+\$d.toboolean().sign().splice(\$Zero,\$d.tocapsules().inverse())```

This equation works by first converting the signal to a boolean (true/false) value where when the value is valid, the result is true. That boolean is then turned into a 1 for true (valid) or 0 for false (not valid) using the .sign() operator. When data does not exist (equipment is offline), the .boolean().sign() operators do not provide a value for the signal. Therefore, the .splice() operator takes those time periods (found by creating capsules for the inverse of all valid data using the .tocapsules().inverse() operators) and adds in a scalar as a zero value to ensure those invalid points exist as zero counts. However, in Seeq versions prior to R21.0.41, the .inverse() operator requires a time argument to ignore all capsules longer than the specified time. As may signals may be offline for months or years, performance can be impacted by long time periods within the .inverse() operator. In this case, the following equation is suggested (recommended prior to R21.0.41):

```\$daily = periods(1day) // creates periodic condition daily
\$Zero = 0.tosignal(1min) // creates a scalar value of 0 to splice in when the values are invalid
\$a.toboolean().sign().splice(\$Zero,\$daily.minus(\$a.tocapsules()))+\$b.toboolean().sign().splice(\$Zero,\$daily.minus(\$b.tocapsules()))+\$c.toboolean().sign().splice(\$Zero,\$daily.minus(\$c.tocapsules()))+\$d.toboolean().sign().splice(\$Zero,\$daily.minus(\$d.tocapsules()))```

Instead of requiring an inverse function that could be impacting performance by looking out years beyond the display range, this equation creates daily capsules to reduce the size of an individual capsule and subtracts the valid capsules from that using the .minus() operator.

Therefore, if you would like to combine the entire average calculation into a single formula, the following formulas are suggested.

R21.0.41 or later:

```\$Zero = 0.tosignal(1min) // creates a scalar value of 0 to splice in when the values are invalid
(\$a+\$b+\$c+\$d)/(\$a.toboolean().sign().splice(\$Zero,\$a.tocapsules().inverse())+\$b.toboolean().sign().splice(\$Zero,\$b.tocapsules().inverse())+\$c.toboolean().sign().splice(\$Zero,\$c.tocapsules().inverse())+\$d.toboolean().sign().splice(\$Zero,\$d.tocapsules().inverse()))```

Prior to R21.0.41:

```\$daily = periods(1day) // creates periodic condition daily
\$Zero = 0.tosignal(1min) // creates a scalar value of 0 to splice in when the values are invalid
(\$a+\$b+\$c+\$d)/(\$a.toboolean().sign().splice(\$Zero,\$daily.minus(\$a.tocapsules()))+\$b.toboolean().sign().splice(\$Zero,\$daily.minus(\$b.tocapsules()))+\$c.toboolean().sign().splice(\$Zero,\$daily.minus(\$c.tocapsules()))+\$d.toboolean().sign().splice(\$Zero,\$daily.minus(\$d.tocapsules())))```

##### Share on other sites

• 4 weeks later...
• Seeq Team

Update:
Adding signals in the numerator with gaps in the data can result in gaps in the summation formula. Therefore, one can use a similar format to the denominator to sum the numerator:

```\$daily = periods(1day) // creates periodic condition daily
\$Zero = 0.tosignal(1min) // creates a scalar value of 0 to splice in when the values are invalid
((\$a.splice(\$Zero,\$a.tocapsules().inverse()))+(\$b.splice(\$Zero,\$b.tocapsules().inverse()))+(\$c.splice(\$Zero,\$c.tocapsules().inverse()))+(\$d.splice(\$Zero,\$d.tocapsules().inverse())))/(\$a.toboolean().sign().splice(\$Zero,\$daily.minus(\$a.tocapsules()))+\$b.toboolean().sign().splice(\$Zero,\$daily.minus(\$b.tocapsules()))+\$c.toboolean().sign().splice(\$Zero,\$daily.minus(\$c.tocapsules()))+\$d.toboolean().sign().splice(\$Zero,\$daily.minus(\$d.tocapsules())))
```

##### Share on other sites

• 8 months later...

Prior to Seeq Version 21.0.43, if a user wanted to take the average of multiple signals, the following syntax was required in Formula:

`(\$a+\$b+\$c)/3`

However, for Seeq Versions 21.0.43 and more recent, the .average() operator now accepts the following, simpler syntax.

`average(\$a,\$b,\$c)`

This improved syntax is also now supported with the .min() and .max() operators as well.