Jump to content
View in the app

A better way to browse. Learn more.

FMForums.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Average($ListOfValues) doesn't work?

Featured Replies

I am writing a script where I need to calculate the average of a bunch of numbers.  There may be 1 number (where no averaging is calculated) or up to 10 or so.  There may be gaps in the numbers from time to time as well.

 

Set Variable [$CalculatedAvg; Value:Average($ListOfValues)]

Doesn't work—no variable is created.

 

Can anyone suggest something that could work?  I was hoping to use the Average function because it automatically accounts for blank values.  Not looking forward to having to eliminate blank values, adding up the remaining values and dividing by ValueCount().  Perhaps virtual list with an average summary field?

 

I guess I'm just surprised some of these aggregate functions don't work on a list of values in a variable.

 

I ran some tests in the Data Viewer, and this is the error message I get:

In the function Average, Count, Extend, GetRepetition, Max, Min, NPV, StDev, Sum, GetSummary or GetNthRecord, an expression was found where a field alone is needed.

I guess I'm just surprised some of these aggregate functions don't work on a list of values in a variable.

 

They don't work on lists period.

 

Try

Case (
  IsEmpty ( $myList ) ; "" ;
  ValueCount ( $myList ) = 1 ; $myList ;
  Evaluate ( "Average (" & Substitute ( $myList ; ¶ ; " ; " ) & ")" )
)

I am writing a script where I need to calculate the average of a bunch of numbers.  There may be 1 number (where no averaging is calculated) or up to 10 or so.

 

Where do these numbers come from? Normally, "a bunch of numbers" would be stored in "a bunch of records" - which can be averaged easily.

 

There may be gaps in the numbers from time to time as well.

 

Not sure what you mean by that.

 

 

 

---

Edit:

 

I am guessing, from what you said later, that gaps mean blank values? If so, you could average your list using something like =

Let ( [
prep = Substitute ( TrimAll ( Substitute ( $yourListOfNumbers ;  ¶ ; " " ) ; 0 ; 0 ) ;  " " ; ", ")
] ;
Case (
WordCount ( prep ) ≤ 1 ; prep ;
Evaluate ( "Average ( " & prep & " )" )
)
)

Note, however, that this is not much more than a hack. A better solution to the problem would eliminate it from the start.

Edited by comment

  • Author

 

Yep, I know.  Just surprised, is all.

 

Yes, the "gaps" I speak of are null values.  Average() automatically ignores blanks, so it would have been nice to use it.

 

eos and comment, I spent the time since my original post to try and figure out an alternative, and I came up with a similar method, although it looks like your script steps are probably more error proof.  Here's my custom function, GetAverage(Values):

/*

Purpose
Calculates the average of a list of values.  Useful for when the Average() function does not work.

With inspiration from:
• Debi Fuchs' "CullNulls" (http://www.briandunning.com/cf/897) custom function
• Tom Fitch's "ListSum" (http://www.briandunning.com/cf/1309) custom function

History
2014/10/10 - Matt Larson (Cimbura.com) - Custom function creation

*/

Let(

[
	str = "#||#*howdy*#||#";  //  Unique string used to strip out null values
	v = Substitute(str & Values & str; ["¶¶"; ¶ & str & ¶]; ["¶¶"; ¶ & str & ¶]; [str & ¶; ""]; [¶ & str; ""]; [str; ""]);  //  Strip out unwanted carriage returns
	v = Substitute(v; "¶"; ";")  //  Convert carriage returns to semicolons for use in Average() function
];

Evaluate("Average(" & v & ")")

)

I was pretty vague with "bunch of numbers", wasn't I?   :)  Sorry.  They are actually the results of an ExecuteSQL script step, so I wanted to avoid having to needlessly navigate to a different layout, set up additional summary fields, etc.

 

Thanks a lot guys.

I was pretty vague with "bunch of numbers", wasn't I?   :)  Sorry.  They are actually the results of an ExecuteSQL script step,

 

Then you could use SQL's AVG() (which also ignores NULL values).

 

Alternatively, use an SQL query that in the WHERE clause includes the predicate " … theNumberField IS NOT NULL".

  • Author

Ahh, advanced SQL coding techniques…  Probably beyond my ability (and time) at this point.

 

I just updated my skill level in my profile to "Expert" but I think you are ahead of me.   :worship:

v = Substitute(str & Values & str; ["¶¶"; & str & ¶]; ["¶¶"; & str & ¶]; [str & ¶; ""]; & str; ""]; [str; ""]); // Strip out unwanted carriage returns

 

Interesting technique...One issue though is it breaks if there's a leading Null value.

 

I'd modify it to something I learned from comment:

 

Substitute ( TrimAll (  Substitute ( Values ; [ "¶" ; " " ] ) ; 0 ; 0 ) ; " " ; ";" )

Ahh, advanced SQL coding techniques…  Probably beyond my ability (and time) at this point.

 

Not really advanced … and it should require a lot less time and effort to use

 

ExecuteSQL ( " SELECT AVG ( myNumberField ) FROM myTable " ; "" ; "" )

 

than cleaning up a list in order to Evaluate() it – all of which eventually amounts, as comment noted quite correctly, to just a hack.

 

 

I just updated my skill level in my profile to "Expert"

 

I guess everybody's an expert in something …  :D as can be observed here

Create an account or sign in to comment

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.