This article will cover the translation of the Sheets workbook Array type functions for Apps Script. Most of them will be covered, except for a few exotic ones that I might do later if anybody asks, and some are partial implementation omitting some of the edge case options.
Motivation
If you are handling data from sheets it might be useful to use the same logic as is available in the worksheet for common tasks rather than reinventing them. Some of the array functions for Matrix handling and forecasting are quite tricky, so if you need to do any of that in Apps Script, these might be handy.
Background
For some general introduction on implementation see Sheets Workbook functions – converted to Apps Script
Inputs and Outputs
All inputs to these formulas should be in spreadsheet values format – ie [[x,x..],[y,y..]]. In some cases, these might be flattened where a single result is expected (eg sumproduct), but any results that are arrays will be in the same 2d array format.
ArrayFormula
The Arrayformula function provides a way to repeat operations across an array from a spreadsheet. It’s esentially just a rows.map(…) type operation so I haven’t implemented anything for that as it would end up being more complex that just doing it in native Apps Script.
MathJs
Behind the scenes I’m using mathjs for some of the math, and it’s exposed from the bmSheet library in case you want to use it directly for anything natively. You can get to it via bmSheet.Mathjs. It’s a great resource if you’re doing complex maths.
Accessing functions
All functions are accessible as follows
Functions
I’ll show how to call them, as well as the implementation code which might be of interest.
Handy functions
There are a couple of handy functions that are used throughout.
Workbook functions
These functions are exposed and can be used from apps script. The documentation below is adapted from the official Sheets functions writeups.
array_constrain (input, num_rows, num_cols)
Constrains and returns an array result to a specified sizeARRAY_CONSTRAIN(input, num_rows, num_cols)
input
– The values array to constrainnum_rows
– The number of rows the result should contain.num_cols
– The number of columns the result should contain
frequency (data, classes)
Calculates the frequency distribution of a one-column array into specified classes.
FREQUENCY(data, classes)
data
– The array containing the values to be counted.classes
– The array or range containing the set of classes.
Notes
- The output of
FREQUENCY
will be a vertical range of size one greater thanclasses
as the final value is the number of elements indata
greater than any of the class boundaries.
growth (known_data_y, [known_data_x], [new_data_x], [b]
)
This is a partial implementation – it flattens all arrays, so can only deal with 1 dependent variable at once, unlike the sheet function which has an option to handle multiple dependent variables.
Given partial data about an exponential growth trend, fits an ideal exponential growth trend and/or predicts further values.
GROWTH(known_data_y, [known_data_x], [new_data_x], [b])
known_data_y
– The array or range containing dependent (y) values that are already known, used to curve fit an ideal exponential growth curve.- If
known_data_y
is a two-dimensional array or range,known_data_x
must have the same dimensions or be omitted.
- If
known_data_x
– [ OPTIONAL –{1,2,3,...}
with same length asknown_data_y
by default ] – The values of the independent variable(s) corresponding withknown_data_y
.new_data_x
– [ OPTIONAL – same asknown_data_x
by default ] – The data points to return they
values for on the ideal curve fit.- The default behavior is to return the ideal curve fit values for the same
x
inputs as the existing data for comparison of knowny
values and their corresponding curve fit estimates.
- The default behavior is to return the ideal curve fit values for the same
b
– [ OPTIONAL –TRUE
by default ] – Given a general exponential form ofy = b*m^x
for a curve fit, calculatesb
ifTRUE
or forcesb
to be1
and only calculates them
values ifFALSE
.
linest (known_data_y, [known_data_x], [calculate_b]
)
This is a partial implementation, only supports 1 dependent variable and has no verbose option.
LINEST(known_data_y, [known_data_x], [calculate_b])
Given partial data about a linear trend, calculates various parameters about the ideal linear trend using the least-squares method.
known_data_y
– The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.- If
known_data_y
is a two-dimensional array or range,known_data_x
must have the same dimensions or be omitted.
- If
known_data_x
– [ OPTIONAL –{1,2,3,...}
with same length asknown_data_y
by default ] – The values of the independent variable(s) corresponding withknown_data_y
.calculate_b
– [ OPTIONAL –TRUE
by default ] – Given a linear form ofy = m*x+b
, calculates the y-intercept (b
) ifTRUE
. Otherwise, forcesb
to be0
and only calculates them
values ifFALSE
, i.e. forces the curve fit to pass through the origin.
logest (known_data_y, [known_data_x]
)
This is a partial implementation, only supports 1 dependent variable and has no verbose option.
LOGEST(known_data_y, [known_data_x])
Given partial data about an exponential growth curve, calculates various parameters about the best fit ideal exponential growth curve.
known_data_y
– The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.- If
known_data_y
is a two-dimensional array or range,known_data_x
must have the same dimensions or be omitted.
- If
known_data_x
– [ OPTIONAL –{1,2,3,...}
with same length asknown_data_y
by default ] – The values of the independent variable(s) corresponding withknown_data_y
.
mdeterm (square_matrix
)
Returns the matrix determinant of a square matrix specified as an array or range.
MDETERM(square_matrix)
square_matrix
– An array or range with an equal number of rows and columns representing a matrix whose determinant will be calculated.
minverse (square_matrix
)
Returns the multiplicative inverse of a square matrix specified as an array or range.
MINVERSE(square_matrix)
square_matrix
– An array or range with an equal number of rows and columns representing a matrix whose multiplicative inverse will be calculated.
mmult (matrix1, matrix2
)
Calculates the matrix product of two matrices specified as arrays or ranges.
MMULT(matrix1, matrix2)
matrix1
– The first matrix in the matrix multiplication operation, represented as an array or range.matrix2
– The second matrix in the matrix multiplication operation, represented as an array or range.
Notes
- As standard in matrix multiplication, the number of columns for
matrix1
must equal the number of rows formatrix2
sumproduct (array1, [array2, ...]
)
This function returns a single result. I’ve made it a little more flexible than the sheet function as you can provide a single value rather than an array that each element will be multiplied by, and all the arrays are flattened, so they don’t have to be the same shape – just have the same number of total elements. This will allow it to be used on more than just spreadsheet shaped data.
The SUMPRODUCT function calculates the sum of the products of corresponding entries in 2 equally sized arrays or ranges.
SUMPRODUCT(array1, [array2, ...])
array1
– The first array whose entries will be multiplied with corresponding entries in the second such array or range.array2, ...
– [ OPTIONAL –{1,1,1,...}
with same length asarray1
by default ] – The second array whose entries will be multiplied with corresponding entries in the first such array or range.
transpose (array
)
Transposes the rows and columns of an array or range of cells.
TRANSPOSE(array)
array
– The array or range whose rows and columns will be swapped.
Notes
- Transposition operates such that the value in the nth row and mth column will become the value in the mth row and nth column. E.g. the value in the fourth row and second column will be put into the second row and fourth column. The result of a transposition on a range of size m rows by n columns is therefore n rows by m columns.
trend (known_data_y, [known_data_x], [new_data_x], [b]
)
This is a partial implementation, only supports 1 dependent variable.
TREND(known_data_y, [known_data_x], [new_data_x])
-
known_data_y
– The array or range containing dependent (y) values that are already known, used to curve fit an ideal linear trend.- If
known_data_y
is a two-dimensional array or range,known_data_x
must have the same dimensions or be omitted.
- If
known_data_x
– [ OPTIONAL –{1,2,3,...}
with same length asknown_data_y
by default ] – The values of the independent variable corresponding withknown_data_y
.new_data_x
– [ OPTIONAL – same asknown_data_x
by default ] – The data points to return they
values for on the ideal curve fit.- The default behavior is to return the ideal curve fit values for the same
x
inputs as the existing data for comparison of knowny
values and their corresponding curve fit estimates.
- The default behavior is to return the ideal curve fit values for the same
flatten (array
)
Flattens all the values from one or more ranges into a single column.
Parts of a FLATTEN function
=FLATTEN(range1, [range2, …])
Part | Description |
range1 | The first range to flatten. |
range2 | [optional] repeatable
Additional ranges to flatten. |
Notes
- Values are ordered by argument, then row, then column. So, the entire first row of an input is added before the second row (also known as row-major order).
- Empty values are not skipped; the FILTER function can be used to remove those.
Testing as worksheet custom functions
Normally these functions are going to be called from Apps Script. There’s no real reason to access these functions as custom functions from a spreadsheet, except that it’s useful to check the results by comparing them against the real thing.
If you want to do this, you can add this code to your container bound script to expose all the functions as custom functions in your sheet.
You can then call them like this
Calling the same thing from apps script would look like this
Links
library: 1B4T8Ec3Mlmqj91vnn_oqhBfjcEiVl3EcRS_1gIkdeJCDEvy5u5x3jRHT
bmSheet: IDE
github: https://github.com/brucemcpherson/bmSheet
scrviz: https://scrviz.web.app?manifest=brucemcpherson%2FbmSheet%2Fappsscript.json
Temporal – dates, times and timezones and the proposed new Date system for ECMAScript
Sheets Workbook functions – converted to Apps Script
- Currency exchange rates library for Apps Script – optimized for the parsimonious – swop.cx
- Sheets Workbook functions in Apps Script – Date and Time and Temporal primer
- Sheets Workbook functions in Apps Script – Array functions
- Sheets Workbook functions in Apps Script – Database functions
- Sheets Workbook functions in Apps Script – Filter functions
- SQL for Apps Script – it’s here