Have a column that contains text separated by a ',' and I am trying to work out the fraction of occurrences for each string in the column as detailed below
a,b
a
g,g,f
a
b
b,a,f,f
Output needed in another column
0.5
1
0.33
1
1
0.25
Not sure the best approach here is to use a query and SQL do this? I'm sure there is a simple way?
My current thinking
=QUERY(IF D3 contains "," (len(D3)-len(SUBSTITUTE(D3,",","")) else 1))
Assuming your data starting in D3, try
=arrayformula(if(len(D3:D), trunc(1/len(substitute(D3:D, ",",)),2),))
and see if that works?
(Change range to suit)
SPLIT by ,
Divide 1 by COUNT of the resulting array
=1/COUNTA(SPLIT(A2,","))
Related
I'm trying to write a formula where I can generate a number n number of times where n can be the input provided by the user.
=ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(
REPT($D2&",", $E2), ), ","))))
Ideal output
Here D2 is the value to be repeated and E2 is the number of times.
So instead of manually using this formula after each last repeated value to generate the next set of repeated values, I want to print the values in one go. I'll be really grateful, if anyone could please provide a way around to do the same. Thanks in advance.
Try this
=ARRAY_CONSTRAIN(arrayformula(query(flatten(split(rept("|"&D2:D,E2:E),"|")),"select * where Col1 is not null")),SUM(E2:E),1)
explanation
the core of the formula is
=arrayformula(iferror(split(rept("|"&D2:D,E2:E),"|")))
then, apply flatten with a limitation of rows (ARRAY_CONSTRAIN) equal to the sum of column E, and query only the rows that are not null
Try the below formula:
=ARRAYFORMULA(TRIM(TRANSPOSE(SPLIT(QUERY(
REPT(D2:D&",", E2:E), ,999^99), ","))))
I have managed to make this formula:
=IF(COUNTIF($A$1:A1,A1)=$B$1,A1+1,A1)
Is making an incremental list in the same column, starting with 01, and on cell B1 I am instructing how many times this number should repeat (up to 5 times per number). So, if I say repeat 2 times it looks like this:
Column A
1
1
2
2
How can I make it an Array Formula? I'm barely starting on Arrays so I'm just trying to learn as I go.
you can try to solve this with the following formula =ArrayFormula(flatten(if(SEQUENCE(1,C1),SEQUENCE(C2)))) but you should specify the value limit in cell C2 to which the numbers must increase, otherwise the formula will loop
Try this
=ARRAY_CONSTRAIN(arrayformula(query(flatten(split(rept("|"&A2:A,B2:B),"|")),"select * where Col1 is not null")),SUM(B2:B),1)
https://docs.google.com/spreadsheets/d/1qXy-hzWUnsUmAa-8aV5IHOyZABGD_h8ajICLwdyNge8/edit?usp=sharing
Try Sequence() with ROUNDUP() function.
=ArrayFormula(ROUNDUP(SEQUENCE(B1*B1)/B1,0))
When enter 3:
I'm sure there's a pretty simple solution, but I cant' get to it.
I'm trying to sum a list of numbers, but only the values that are round numbers/whole integers.
Eg column A:
1
1.5
3
2.4
2
sum of the whole numbers
1 + 3 + 2 = 6
Any hint?
Let's suppose your numbers list begins in A2 and runs downward (i.e., A2:A). You can use this:
=SUM(FILTER(A2:A,A2:A=INT(A2:A)))
In plain English, this reads as follows: "Sum only those numbers in A2:A where the original value is the same as the integer-only portion of that value."
Try:
=sumproduct((A1:A5)*(A1:A5=int(A1:A5)))
this will also work in Excel
use dot detection:
=INDEX(SUM(IF(REGEXMATCH(""&A:A, "\."),,A:A)))
Another solution, you can use SEARCH to search for the decimal point:
=SUM(A1:A)-SUM(FILTER(A1:A,SEARCH(".",TO_TEXT(A1:A))))
or =SUM(FILTER(A1:A,NOT(ISNUMBER(SEARCH(".",A1:A)))))
as JvdV mentioned in his comment.
Either try QUERY():
=SUM(QUERY(A:A,"where A matches '\d+'"))
Or FILTER():
=SUM(FILTER(A:A,MOD(A:A,1)=0))
Note: This 1st option makes use of the possibility to use a regular expression inside the "where" clause of QUERY(). Use =SUM(QUERY(A:A,"where A matches '-?\d+'")) if you want to account for positive and negative integers.
I have a column which won't sum? it sits beside a column with an array formula how is a sum done in this case?
This is my formula in C3:
ArrayFormula(query({M8Report!A2:T,arrayformula(left(regexreplace(M8Report!N2:N, "\n|\r", ""),150))},"Select Col5,Col2,Col1,Col21,Col3 Where (Col4 = 'Work Order') order by Col5", -1))
in B I have entered integer values in B1 I have =sum(B3:B) and the result is always 0 if instead in B1 I use B3+B4+B5+etc.. I get the correct result...
..Tried everything I can think of and same issue sum =0
since C is dynamic I need a way to sum all of the values in B
..any ideas would be helpful
In your sample sheet your formula is:
= { QUERY ; { "TOTAL" , SUM(B3:B) } }
Change it to:
=CONCAT("TOTAL ", SUM(B3:B))
The error has to do with your use of the {}, which is used to define an array literal. You just want to have 2 strings merged where one is the sum of the values. Also note that you may want to use B4:B instead since B3 is a header for the data below that.
Last, make sure the data is Numbers. The original data is formatted as Plain Text so SUM() has nothing to add.
to ditch formatting issues you can do:
={"Total", SUMPRODUCT(B5:B)}
I'm trying to find the inverse rank within categories using an ArrayFormula. Let's suppose a sheet containing
A B C
---------- -----
1 0.14 2
1 0.26 3
1 0.12 1
2 0.62 2
2 0.43 1
2 0.99 3
Columns A:B are input data, with an unknown number of useful rows filled-in manually. A is the classifier categories, B is the actual measurements.
Column C is the inverse ranking of B values, grouped by A. This can be computed for a single cell, and copied to the rest, with e.g.:
=1+COUNTIFS($B$2:$B,"<" & $B2, $A$2:$A, "=" & $A2)
However, if I try to use ArrayFormula:
=ARRAYFORMULA(1+COUNTIFS($B$2:$B,"<" & $B2:$B, $A$2:$A, "=" & $A2:$A))
It only computes one row, instead of filling all the data range.
A solution using COUNT(FILTER(...)) instead of COUNTIFS fails likewise.
I want to avoid copy/pasting the formula since the rows may grow in the future and forgetting to copy again could cause obscure miscalculations. Hence I would be glad for help with a solution using ArrayFormula.
Thanks.
I don't see a solution with array formulas available in Sheets. Here is an array solution with a custom function, =inverserank(A:B). The function, given below, should be entered in Script Editor (Tools > Script Editor). See Custom Functions in Google Sheets.
function inverserank(arr) {
arr = arr.filter(function(r) {
return r[0] != "";
});
return arr.map(function(r1) {
return arr.reduce(function(rank, r2) {
return rank += (r2[0] == r1[0] && r2[1] < r1[1]);
}, 1);
});
}
Explanation: the double array of values in A:B is
filtered, to get rid of empty rows (where A entry is blank)
mapped, by the function that takes every row r1 and then
reduces the array, counting each row (r2) only if it has the same category and smaller value than r1. It returns the count plus 1, so the smallest element gets rank 1.
No tie-breaking is implemented: for example, if there are two smallest elements, they both get rank 1, and there is no rank 2; the next smallest element gets rank 3.
Well this does give an answer, but I had to go through a fairly complicated manoeuvre to find it:
=ArrayFormula(iferror(VLOOKUP(row(A2:A),{sort({row(A2:A),A2:B},2,1,3,1),row(A2:A)},4,false)-rank(A2:A,A2:A,true),""))
So
Sort cols A and B with their row numbers.
Use a lookup to find where those sorted row numbers now are: their position gives the rank of that row in the original data plus 1 (3,4,2,6,5,7).
Return the new row number.
Subtract the rank obtained just by ranking on column A (1,1,1,4,4,4) to get the rank within each group.
In the particular case where the classifiers (col A) are whole numbers and the measurements (col B) are fractions, you could just add the two columns and use rank:
=ArrayFormula(iferror(rank(A2:A+B2:B,if(A2:A<>"",A2:A+B2:B),true)-rank(A2:A,A2:A,true)+1,""))
My version of an array formula, it works when column A contains text:
=ARRAYFORMULA(RANK(ARRAY_CONSTRAIN(VLOOKUP(A1:A,{UNIQUE(FILTER(A1:A,A1:A<>"")),ROW(INDIRECT("a1:a"&COUNTUNIQUE(A1:A)))},2,)*1000+B1:B,COUNTA(A1:A),1),ARRAY_CONSTRAIN(VLOOKUP(A1:A,{UNIQUE(FILTER(A1:A,A1:A<>"")),ROW(INDIRECT("a1:a"&COUNTUNIQUE(A1:A)))},2,)*1000+B1:B,COUNTA(A1:A),1),1) - COUNTIF(A1:A,"<"&OFFSET(A1,,,COUNTA(A1:A))))