arraysgoogle-sheetsarray-formulasflattenstdev

STDEV ARRAYFORMULA in Google Sheets


since STDEV is not supported under ARRAYFORMULA there is either draggable solution:

enter image description here

or hardcoded solution:

enter image description here

but neither of them is dynamically scalable so is there any workaround?

from a quick google search, it looks like no one dared to dream of such lengths

data sample:

b   5
a   1
a   2
b   5
a   1

desired result:

a   0.5773502692
b   0

Solution

  • the math says that standard deviation can be achieved as:

    enter image description here

    if we substitute for formulae we get:

    enter image description here

    knowing the above we can easily convert it into a multidimensional array... let's start with the first query where we pivot labels:

    enter image description here

    removing labels:

    enter image description here

    calculating the average:

    enter image description here

    removing labels:

    enter image description here

    for subtraction, we need to exclude empty cells so we use IF:

    enter image description here

    and raise it on the 2nd power:

    enter image description here

    now we can sum it up per column with MMULT or QUERY again:

    enter image description here

    to make it more dynamic we can construct query selection with SEQUENCE:

    enter image description here

    next is division by count:

    enter image description here

    then square root:

    enter image description here

    now we just add back labels:

    enter image description here

    and transpose it:

    =ARRAYFORMULA(TRANSPOSE({INDEX(QUERY({A:B}, 
     "select max(Col2) where Col1 is not null group by Col2 pivot Col1"), 1); 
     (QUERY(QUERY(IF(QUERY(QUERY({A:B, ROW(A:A)}, 
     "select max(Col2) where Col2 is not null group by Col3 pivot Col1"), "offset 1", )="",,
     (QUERY(QUERY({A:B, ROW(A:A)}, 
     "select max(Col2) where Col2 is not null group by Col3 pivot Col1"), "offset 1", )-
     QUERY(QUERY({A:B, ROW(A:A)/0}, 
     "select avg(Col2) where Col2 is not null group by Col3 pivot Col1"), "offset 1", ))^2), 
     "select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(COUNTUNIQUE(A:A))&")")), "offset 1", )/
     (INDEX(TRANSPOSE(QUERY({A:B}, 
     "select Col1,count(Col1) where Col1 is not null group by Col1 label count(Col1)''")), 2)-1))^(1/2)}))
    

    enter image description here



    it works, but we can do better... simple IF statement will do:

    enter image description here

    but to make it fast and smart we need some tweaks to counter empty cells and unsorted dataset:

    enter image description here

    we add errors:

    enter image description here

    subtract the average:

    enter image description here

    raise on the 2nd power:

    enter image description here

    remove errors with IFNA and sum it:

    enter image description here

    divide by count-1:

    enter image description here

    take a square root:

    enter image description here

    transpose it and add back labels:

    =INDEX(IFERROR({SORT(UNIQUE(FILTER(A:A, A:A<>""))), FLATTEN(( 
     INDEX(QUERY(IFNA((IF(FILTER(A:A, A:A<>"")=TRANSPOSE(SORT(UNIQUE(
     FILTER(A:A, A:A<>"")))), FILTER(B:B, B:B<>""), NA())-INDEX(QUERY({A:B, ROW(A:A)/0}, 
     "select avg(Col2) where Col2 is not null group by Col3 pivot Col1"), 2))^2), 
     "select "&TEXTJOIN(",", 1, "sum(Col"&SEQUENCE(COUNTUNIQUE(A:A))&")")), 2)/TRANSPOSE(QUERY({A:B}, 
     "select count(Col1) where Col1 is not null group by Col1 label count(Col1)''")-1))^(1/2))}))
    

    enter image description here