I have the following data
X f1 f2 f3
1 20 20/5/2 3
2 0 10/5/0 7
3 15 20/2/1 3
4 30 80/0/9 3
I want to make SUM() of all values in f2 column but it gives me an error because of the /.
How can I take each value, separately?
Plus, how to get each relative percentage of each cell in f2? For example, the first cell of f2 would be 74,07 / 18,52 / 7,41 taken from doing (20/27 - 5/27- 2/27)
use:
=INDEX(SUM(IFERROR(SPLIT(F1:F; "/"); 0)*1))
update:
=ARRAYFORMULA(IF(C1:C="";;SUBSTITUTE(FLATTEN(QUERY(TRANSPOSE(ROUND(
IFERROR(SPLIT(C1:C; "/")/MMULT(1*IFERROR(SPLIT(C1:C; "/"));
SEQUENCE(COLUMNS(SPLIT(C1:C; "/")); 1;;)^0))*100; 2));;9^9)); " "; " / ")))
Related
It is very possible that I dont understand the lambda logic or do I? I have dataset A2:A5 like:
1
3
6
10
If I do: =SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb)) i get:
1
4
10
20
If I do: =SCAN(0, A2:A5, LAMBDA(aa, bb, ROW(bb)-1)) I get
1
2
3
4
if I run: =SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1))) the result is
1
8
42
208
Why there is 42 and 208 ? How this results in such values? How can it be 42 and 208 ?
Expected result is
1
8
30
80
And I can get it with:
=ArrayFormula(SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb))*(ROW(A2:A5)-1))
But not with
=SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1)))
SCAN is a great intermediate results function. To understand how SCAN operates, you need to understand how REDUCE operates. The syntax is:
=REDUCE(initial_value, array, LAMBDA(accumulator, current_value, some_function()))
Going through =SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb)*(ROW(bb)-1))) step by step,
A2:A5 is 1,3,6,10
Step 1:
aa = 0(initial_value)
bb = 1(current_value:A2)
Result((aa+bb)*(ROW(bb)-1)): (0+1)*(2-1)=1
Step 2:
aa = 1(accumulator(previous return value))
bb = 3(current_value:A3)
Result((aa+bb)*(ROW(bb)-1)): (1+3)*(3-1)=8
Step 3:
aa = 8(accumulator(previous return value))
bb = 6(current_value:A4)
Result((aa+bb)*(ROW(bb)-1)): (8+6)*(4-1)=42
Step 4:
aa = 42(accumulator(previous return value))
bb = 10(current_value:A5)
Result((aa+bb)*(ROW(bb)-1)): (42+10)*(5-1)=52*4=208
aa stores the result of the previous calculation, so you have:
above answers pretty much contain all so I will add only this:
you probably expected that by doing (aa+bb)*(ROW(bb)-1) you will get:
(aa+bb)
*
(ROW(bb)-1)
1
*
1
=
1
4
*
2
=
8
10
*
3
=
30
20
*
4
=
80
but that's not how it works. to get your expected result and by not using your formula where ROW is outside of SCAN:
=ArrayFormula(SCAN(0, A2:A5, LAMBDA(aa, bb, aa+bb))*(ROW(A2:A5)-1))
you would need to do:
=INDEX(MAP(SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb))), ROW(A2:A5)-1, LAMBDA(cc, dd, cc*dd)))
where cc is the entire SCAN and dd is ROW(A2:A5)-1 eg. first do the running total and then multiplication, which is not so feasible length-wise.
or shorter but with SEQUENCE:
=MAP(SCAN(0, A2:A5, LAMBDA(aa, bb, (aa+bb))), SEQUENCE(4), LAMBDA(cc, dd, cc*dd))
Consider the following data in GAMS:
set i / 1,2,3 /
j / 1,2,3 /;
parameter stock(i,j);
stock(i,j) = 10;
Consider the following mapping:
set jagg / b1,b2 /
map2(j,jagg) / 1.b1, 2.b1, 3.b2, 4.b2 /;
I can easily mapping using:
parameter stockagg(i,jagg);
stockagg(i,jagg) = sum(map2(j,jagg),stock(i,j));
However, I don't want to map if set i is equal to set j.
That is, I want the following data as my result:
1 1 10
1 b1 10
1 b2 20
2 b1 10
2 2 10
2 b2 20
3 b1 20
3 3 10
3 b2 10
4 b1 20
4 b2 10
4 4 10
Is there an easy way to do that in GAMS?
Not sure, if I got your question completely right, but this give you the result you posted:
set i / 1,2,3,4 /
j / 1,2,3,4,b1,b2 /;
Alias(j,jj);
parameter stock(i,j);
stock(i,j) = 10;
set jagg(j) / b1,b2 /
map2(j,jj) / 1.b1, 2.b1, 3.b2, 4.b2 /;
parameter stockagg(i,j);
stockagg(i,j) = sum(map2(jj,jagg(j))$(not sameas(i,jj)),stock(i,j))$(not sameas(i,j))
+ stock(i,j) $( sameas(i,j));
display stockagg;
I have the following sheet.
H I J K ... BD
2,3 4 2,4,7 ... 1
3,7 10 ... 8,13
The cell ‘H’ has 2,3 as text but cell ’I’ has the number 4, cell ‘J’ has the 2,4,7 as text and cell ‘BD’ has 1 as a number. All the cells that have 2 or more numbers as text are separated by commas
I want to sum all numbers and non-numbers to one single row using array-formula.
The result must be
BE
16
41
The range is between H2:BD with H1:BD1 for the headers
I have used this code:
=arrayformula(if(row(A1:A)=1;"BottleQty";if(len(A1:A)>0;
SUBSTITUTE(transpose(query(transpose(H1:BD);;COLUMNS(H2:BD)));",";"");iferror(1/0))))
but the result is
BE
2 3 4 2 4 7 1
3 7 10 8 13
Any help ??
Thanks in advance
=ARRAYFORMULA(IF(LEN(TRIM(TRANSPOSE(QUERY(TRANSPOSE(A2:D),,99^99)))),
MMULT(IFERROR(SPLIT(TRANSPOSE(QUERY(TRANSPOSE(A2:D),,99^99)), ", ")*1, 0), ROW(INDIRECT("A1:A"&
COLUMNS(IFERROR(SPLIT(TRANSPOSE(QUERY(TRANSPOSE(A2:D),,99^99)), ", ")*1, 0))))^0), ))
I would like to do something like this (Formula to find the header index of the first non blank cell of a range in Excel?) except that I want to capture all the nonblank cells.
An application of what I am expecting would produce column "prod"
2 3 5 7 11 13 | prod |
2 1 2^1
3 1 3^1
4 2 2^2
5 1 5^1
6 1 1 2^1 3^1
7 1 7^1
8 3 2^3
9 2 3^2
10 1 1 2^1 5^1
11 1 11^1
12 2 1 2^2 3^1
13 1 13^1
14 1 1 2^1 7^1
15 1 1 3^1 5^1
16 4 2^4
I wouldn't mind a result with multiple separators ie. 6= 2^1*3^1**** , as they could be removed.
This user defined function will stitch together the header value with the range value.
In a standard public module code sheet:
Option Explicit
Function prodJoin(rng As Range, hdr As Range, _
Optional op As String = "^", _
Optional delim As String = " ")
Dim tmp As String, i As Long
For i = 1 To rng.Count
If Not IsEmpty(rng.Cells(i)) Then
tmp = tmp & delim & hdr.Cells(i).Text & op & rng.Cells(i).Text
End If
Next i
prodJoin = Mid(tmp, Len(delim) + 1)
End Function
On the worksheet as,
If you absolutely must use worksheet functions then stitch 6 conditional concatenations together.
=TRIM(IF(B2, B$1&"^"&B2&" ", TEXT(,))&
IF(C2, C$1&"^"&C2&" ", TEXT(,))&
IF(D2, D$1&"^"&D2&" ", TEXT(,))&
IF(E2, E$1&"^"&E2&" ", TEXT(,))&
IF(F2, F$1&"^"&F2&" ", TEXT(,))&
IF(G2, G$1&"^"&G2&" ", TEXT(,)))
I have arrayformula in the first row of a column so my values and calculations can start in Row 2 and for all the column length.
I have this situation:
https://docs.google.com/spreadsheets/d/11oDra7Vja4-5C0Uix7JTgLLSMG3gPj-6fkajXlWqqQk/edit?usp=sharing
I need a simply arithmetic operation:
Subtract above value of the same column for every row.
I'm using:
=arrayformula(IF(row(A:A)=1; "What I have now"; IF(ISBLANK(A:A); ""; A1:A-A2:A)))
but as you see is wrong.
How to do that?
UPDATED QUESTION:
And then in the second sheet I need a SUM operation with some blank cells in column:
How to do that?
https://docs.google.com/spreadsheets/d/11oDra7Vja4-5C0Uix7JTgLLSMG3gPj-6fkajXlWqqQk/edit#gid=931743679
If you want to have the array formula ion the header this is a bit weird as you need to allow the formula to technically access row 0, we can do this by constructing ranges.
=ArrayFormula(IF(
--(ROW(A1:A) > 2) + -ISBLANK(A1:A) = 1;
{0; A1:A} - {0; A2:A; 0};
""))
--(ROW(A1:A) > 2) + -ISBLANK(A1:A) = 1 Checks if the row is populated and not one of the first two rows in a way that works nicely with array formulas
{0; A1:A} - {0; A2:A; 0} does the following:
0 Data 156 123 110 95 42
- - - - - - -
0 156 123 110 95 42 0
= = = = = = =
0 33 13 15 53 42 42
N N Y Y Y Y N <- Is shown
^ ^ ^
| | Because Row is blank
| |
Because row not > 2, thus it is never evalauated even though the second would cause an error
I think this is quite tricky. The problem is that in an array formula the number of cells in each array must match - you can't mix an array starting in row 1 with an array starting in row 2 if they go all the way to the bottom of the spreadsheet.
Here is one way of getting the result you want
=arrayformula({"What I need";"";offset($A$1,1,0,count(A:A)-1)-offset($A$1,2,0,count(A:A)-1)})
You will need to change the ; and , for your locale.
I have built up an array using the {} notation to define the elements. In my locale a ; means go to the next row, so I have defined the first two cells directly as strings. After that I've chosen to use Offset to get the range A2:A5 (1 row down from A1, 0 rows across and 4 cells high) and subtract the range A3:A6 (2 rows down from A1, 0 rows across and 4 cells high) it so that gives me the other 4 cells.
B1 "What I need"
B2 ""
B3 A3-A2=33
B4 A4-A3=13
B5 A5-A4=15
B6 A6-A5=53
but will need an IF statement adding if there are any blank cells between the numbers.
In the particular case of your updated question where there are fewer numbers in column D than column C, the formula would be
=arrayformula({"Special Case";"";offset($D$1,1,0,count(D:D))+offset($C$1,2,0,count(D:D))})
But in the general case of there being blank cells anywhere, you would have to test everything
=arrayformula({"General Case";"";if(offset($D$1,1,0,rows(C:C)-2)="","",if(offset($C$1,2,0,Rows(C:C)-2)="","",offset($D$1,1,0,rows(C:C)-2)+offset($C$1,2,0,Rows(C:C)-2)))})