I'm looking for a way to create an excel array with n occurences of an x value, n and x being vectors.
Desired behaviour :
|---------------------|------------------|------------------|
| occurences | value | result |
|---------------------|------------------|------------------|
| 3 | 4 | {4;4;4;1;1} |
|---------------------|------------------|------------------|
| 2 | 1 |
|---------------------|------------------|
This is a question similar to this one, except that I want one more dimension. I'm not interested in a VBA answer, I'm looking for a formula.
I've tried playing around with index and concatenation like in the answer to the previously linked question but with no luck until now.
This result will be used in a bigger formula that will sum the m greatest values (I already have that part figured and working, the m value is irrelevant here). You can consider this question as if the occurences are the storage amounts, and I want the sum of the m greatest individual values.
Here's another approach in O365:
=INDEX(B:B,MATCH(SEQUENCE(SUM(A1:A3),1,0),
MMULT(N(ROW(A1:A3)>=TRANSPOSE(ROW(A1:A3))),A1:A3)-A1:A3))
where you're looking up the row number of the output array in the running total of the input counts.
I think it could be modified to work over an arbitrary range but would then be a fairly long formula.
If the inputs aren't in the sheet but coming from an array formula, then still possible but it would be a very long formula.
=FILTERXML("<t><s>" & TEXTJOIN("</s><s>",TRUE,SEQUENCE(3,,4,0),SEQUENCE(2,,1,0)) & "</s></t>","//s")
will return: {4;4;4;1;1} which can be used as part of a larger formula.
Related
Objective
I have a Microsoft Excel spreadsheet containing a price list that may change over time (B2:B5 in the example). Separately, I have a budget that too may change over time (D2). I am attempting to construct a formula for E2 to output the number of items that can be purchased with the budget in D2. Thereafter, I'll attempt to construct formulas to output any change that would be made (F2) and a comma-delimited list of purchasable items (G2).
Note: It unfortunately isn't possible to add an intermediate calculation column to the list, such as a running total. As such, I'm trying for formulas for single cells (i.e., E2, F2, and G2).
Note: I'm using Excel for Mac 2019.
A B C D E F G
+---------+---------+-----+---------+-------+---------+---------------------------+
1 | Label | Price | | Budget | Items | Change | Item(s) |
+---------+---------+-----+---------+-------+---------+---------------------------+
2 | Item #1 | $ 10.00 | | $ 40.00 | 3 | $ 4.50 | Item #1, Item #2, Item #3 |
+---------+---------+-----+---------+-------+---------+---------------------------+
3 | Item #2 | $ 20.00 | | | | | |
+---------+---------+-----+---------+-------+---------+---------------------------+
4 | Item #3 | $ 5.50 | | | | | |
+---------+---------+-----+---------+-------+---------+---------------------------+
5 | Item #4 | $ 25.00 | | | | | |
+---------+---------+-----+---------+-------+---------+---------------------------+
6 | Item #5 | $ 12.50 | | | | | |
+---------+---------+-----+---------+-------+---------+---------------------------+
For E2, I've attempted:
{=MAX(N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)*ROW($B$2:$B$6)-MIN(ROW($B$2:$B$6))+1)}
Though, the above values and this formula result in an output of -1.
Note: The formula for F2 and G2 seemingly easily follow E2; e.g. {=$D2-SUM(IF((ROW($B$2:$B$6)-MIN(ROW($B$2:$B$6))+1)<=$E2,$B$2:$B$6,0))} and {=TEXTJOIN(", ",TRUE,INDIRECT("$A$2:$A$"&(MIN(ROW($B$2:$B$6))+$E2-1)))} seem to work well, respectively.
Observations
{="$B$2:$B$"&ROW($B$2:$B$6)} evaluates to {"$B$2:$B$2";"$B$2:$B$3";...;"$B$2:$B$6"} (as desired);
{=INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)) should evaluate to the equivalent of {{$B$2:$B$2},{$B$2:$B$3},...,{$B$2:$B$6}}; though, as a 1x5 multi-cell array formula, evaluates to the equivalent of {#VALUE!,#VALUE!,#VALUE!,#VALUE!,#VALUE!} and, with F9 does to {10;#N/A;#N/A;#N/A;12.5};
{=SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2}, as a 1x5 multi-cell array formula, evaluates to the equivalent of {TRUE;TRUE;TRUE;FALSE;FALSE} (as desired); though, with F9 does to #VALUE!;
{=N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)}, as a 1x5 multi-cell array formula, evaluates to the equivalent of 1;1;1;0;0 (as desired); though, with F9 does again to #VALUE!;
{=N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)*ROW($B$2:$B$6), as as 1x5 multi-cell array formula, evaluates to the equivalent of {2,3,4,0,0} (as desired); though, with F9 does to {#VALUE!,#VALUE!,#VALUE!,#VALUE!,#VALUE!};
{=N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)*ROW($B$2:$B$6)-MIN(ROW($B$2:$B$6))+1}, as a 1x5 multi-cell array formula, evaluates to the equivalent of {1,2,3,-1,-1} (as desired); though, with F9 does again to {#VALUE!,#VALUE!,#VALUE!,#VALUE!,#VALUE!}; and,
{=MAX(N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)*ROW($B$2:$B$6)-MIN(ROW($B$2:$B$6))+1)} evaluates to -1
Interestingly:
If {=N(SUM(INDIRECT("$B$2:$B$"&ROW($B$2:$B$6)))<=$D2)*ROW($B$2:$B$6)-MIN(ROW($B$2:$B$6))+1} is placed as the multi-cell array formula in, say, E10:E14, a =MAX($E$10:$E$14) results in 3 (as desired).
Speculation
At present, I'm speculating that, when entered as a single cell array formula, the INDIRECT is not being assessed to be array producing and/or the SUM, as part of a single cell array formula, is not producing an array result.
Please assist. And, thank you in advance.
Solutions (Thanks to Contributors Below)
For E2, {=IF($B$2<=$D2,MATCH(1,0/(MMULT(N(ROW($B$2:$B$6)>=TRANSPOSE(ROW($B$2:$B$6))),$B$2:$B$6)<=$D2)),0)} (thank you Jos Woolley);
For F2, =IF($E2=0,MAX(0,$D2),$D2-SUM($B$2:INDEX($B$2:$B$6,$E2))) (thank you P.b); and,
For G2, =IF($E2=0,"",TEXTJOIN(", ",TRUE,$A$2:INDEX($A$2:$A$6,$E2))) (thank you P.b).
The first point to make, as I mentioned in the comments, is that it must be understood that piecemeal evaluation of a formula - via highlighting subsections of that formula and committing with F9 within the formula bar - will not necessarily correspond to the actual evaluation.
Evaluation via F9 in the formula bar always forces that part to be evaluated as an array. Though this is misleading, since the overall construction may not actually evaluate that part as an array.
The second point to make is that SUM cannot iterate over an array of ranges, though SUBTOTAL, for example, can, so replacing SUM with SUBTOTAL (9, in your current formula should work.
However, you would still be left with a construction which is volatile, so I would recommend this non-volatile alternative:
=MATCH(1,0/(MMULT(N(ROW(B2:B6)>=TRANSPOSE(ROW(B2:B6))),B2:B6)<=D2))
In E2 you can use:
=MATCH(TRUE,--SUBTOTAL(9,OFFSET(B2:B6,,,ROW(B2:B6)))>=D2,0)
In F2 you can use:
=D2-SUM(B2:INDEX(B2:B6,E2))
In G2 you can use:
=TEXTJOIN(", ",1,A2:INDEX(A2:A6,E2))
I need an excel formula that will look at the cell and if it contains an x will treat it as a 8 and add it to the total at the bottom of the table. I have done these in the pass and I am so rusty that I cannot remember how I did it.
Generally, I try and break this sort of problem into steps. In this case, that'd be:
Determine if a cell is 'x' or not, and create new value accordingly.
Add up the new values.
If your values are in column A (for example), in column B, fill in:
=if(A1="x", 8, 0) (or in R1C1 mode, =if(RC[-1]="x", 8, 0).
Then just sum those values (eg sum(B1:B3)) for your total.
A | B
+---------+---------+
| VALUES | TEMP |
+---------+---------+
| 0 | 0 <------ '=if(A1="x", 8, 0)'
| x | 8 |
| fish | 0 |
+---------+---------+
| TOTAL | 8 <------ '=sum(B1:B3)'
+---------+---------+
If you want to be tidy, you could also hide the column with your intermediate values in.
(I should add that the way your question is worded, it almost sounds like you want to 'push' a value into the total; as far as I've ever known, you can really only 'pull' values into a total.)
Try this one for total sum:
=SUMIF(<range you want to sum>, "<>" & <x>, <range you want to sum>)+ <x> * COUNTIF(<range you want to sum>, <x>)
I'm a self-taught programmer currently teaching some kids how to program conversions between the Hebrew and Gregorian calendars. I've got a basic confusion about the lack of a year zero on the historical (Gregorian and Julian) calendars and I seem to be too dense to understand the explanation at https://en.wikipedia.org/wiki/Year_zero.
Here's how I understand a regular number line:
-2 -1 0 1 2 integer number line
----|------|------|------|------|----
<=-2|<===-1|<===-0|0====>|1====>|2==> item labels
3rd | 2nd | 1st | 1st | 2nd | 3rd ordinal numbers
There's one zero, and then positive and negative instances of all the other integers. The item between 0 and +1 is labeled '0' (as an array index or, for instance as an age—a baby isn't 1 year old until its second year.)
But historical calendars don't have a year zero so a regular number line doesn't work, but the labels and ordinal numbers line up:
? ? ? ? ?
----|------|------|------|------|----
<=-3|<===-2|<===-1|1====>|2====>|3==>
3rd | 2nd | 1st | 1st | 2nd | 3rd
As per the article (if I'm following it correctly), astronomical calendars add a year zero before 1 AD/CE:
? ? ? ? ?
----|------|------|------|------|----
<=-2|<===-1|<====0|1====>|2====>|3==>
3rd | 2nd | 1st | 1st | 2nd | 3rd
What I'm confused about is how to assign number line symbols or array indices for either historical or astronomical calendars.
On a regular number line, the interval between -1 and 0 has a label of -0 (in the one's place), and it contains numbers like -0.1 and -0.2. But arrays don't usually have negative indices since it's hard to distinguish between +0 and -0.
—Ok, now that I've explained this far, I think I can answer my own question, which I will do below. But if someone else gives a clearer or better answer, I'm happy to select it.
It is actually ok to give array negative indices. The number line looks like this:
-2 -1 0 1 2 integers
----|------|------|------|------|----
<=-3|<===-2|<===-1|0====>|1====>|2==> array indices
3rd | 2nd | 1st | 1st | 2nd | 3rd
The range between -1 and 0 is labeled -1 because it starts with -1, so the lack of symmetry around 0 for these is fine, and on the negative side, labels match ordinal numbers even though they don't on the positive side.
The thing that was throwing me off was that the astronomical calendar shifts the labels left one unit.
Since the traditional number line is symmetrical in all three, point labels, interval labels, and ordinal labels, I thought that the astronomical calendar would have to add a year zero on both sides of the origin, even though historical calendars only get rid of a single year zero.
Whether this lengthy exercise helps anyone, it did help me. Thanks, StackOverflow!
In meeting with the kids we also figured out that arrows pointing in two directions away from the origin is appropriate for number lines and is good for symmetry around the origin. But array listings and calendar time are appropriately represented as proceeding from left to right, which makes symmetry impossible even if there is a zero point with negative numbers to the left. So, here are the various labelings with more sensible arrows:
-2 -1 0 1 2 integers
----|------|------|------|------|----
| | | 1st | 2nd | 3rd ordinal labels
<=-2|<===-1|<===-0|0====>|1====>|2==> real number interval labels
-3=>|-2===>|-1===>|0====>|1====>|2==> array indices
-3=>|-2===>|-1===>|1====>|2====>|3==> historical calendar years
-2=>|-1===>|0====>|1====>|2====>|3==> astronomical calendar years
I am trying to make a 2D array in LC3. So far I am thinking of initializing a block of memory using .BLKW and then loading into that another array into each entry. This doesn't seem like it will lead me on the right track though. Any suggestions?
You can definitely do it with .BLKW and also with .STRINGZ, though the latter is admittedly a bit unusual.
The bigger, usual question is around how you decide to "get" and "put" data into that specific area of memory. There are several ways to do that for sure (no one right answer).
Your initial thoughts are cool and valid, but definitely seem to me to be more complex, especially in LC3.
A more direct "row major" or "column major" form of storage - where successive memory locations represent the next entry in a row (row major), or alternatively the next entry in a column (column major)) - is the standard way to do this.
Basically you want to allocate that area of memory, and then write two functions: one to put an item at location (r, c), and get an item from location (r,c).
For this, you will hopefully only need to put an item that is small enough to fit into on 16bit memory location for LC3. That could be a number, or a character. (bigger than 16 bit is doable but adds more complexity for your program for sure).
If you want a fully roughed out sample, you can find that here: http://lc3tutor.org/#array2Dcolordersmp (or just go to lc3tutor.org and look at the 2D array sample).
If you are wanting to learn and try this on your own, you can just read the description there and ignore the sample code (best if you doing for homework and you want to be sure you learn it). Otherwise, the code there should run fine in the browser-based lc3 simulator you find referenced there.
Good luck!
Jeff
PS Here's the pre-amble to that code, if you want to just work from this... hopefully this example helps anchor the col major approach taken in the full code sample:
.ORIG x3000
BR MAIN; jump over storage below to the start of the main section
.STRINGZ "ABCDEFGHIJKLMNOPQRSTUVWZYZ"; slightly tricky - we are storing a sequence of letters in our 2D array for reference.
; The address of the above string STARTS AT x3001,
; which you will see is the same as the 2D_ARRAY label value below.
; This is essentially our 2D_ARRAY, starting at x3001 and taking up 26 locations,
; plus 1 (for the null terminator on the string).
; We will assume the 2D array has 13 rows and 2 columns.
; Two letters per row and 13 letters per column. 26 letters.
; So our NUM_ROW label will be 13 and our NUM_COL label will be 2. (see labels below)
; We will treat this array as a column-major stored array.
; Based on our string above, that means the cells of the first
; column (column #0 by our conventions) are: A-M.
; And the cells of the second column (column #1) are: N-Z.
; If we were storing the array in row-major form, then the cells of the first ROW
; would be A, B, and the second ROW would be C, D. Etc.
; Like this:
;
;R\C | 0 | 1
; ------------
; 0 | A | N
; 1 | B | O
; 2 | C | P
; 3 | D | Q
; 4 | E | R
; 5 | F | S
; 6 | G | T
; 7 | H | U
; 8 | I | V
; 9 | J | W
; 10 | K | X
; 11 | L | Y
; 12 | M | Z
; such that 2D_ARRAY[ROW=8, COL=1] would be the letter "V"
I have a very small question related to unsupervised learning because my teacher have not use this word in any lectures. I got this word while reading tutorials. Does this mean if values are same to initial values in last iteration of clusters then it is called converge? for example
| c1 | c2 | cluster
| (1,0) | (2,1)|
|-------|------|------------
A(1,0)| .. |.. |get smallest value
B(0,1)|.. |... |
c(2,1)|.. |... |
D(2,1)|.. |.... |
now after performing n-iteration and if values come same in both c1 and c2 that is (1,0) and (2,1) in last n-th iteration and taking avg if other than single , is it convergence?
Ideally, if the values in the last two consequent iterations are same then the algorithm is said to have converged. But often people use a less strict criteria for convergence, like, the difference in the values of last two iterations is less than a particular threshold etc,.
Incase of K-means clustering, the word convergence means the algorithm have successfully completed this clustering or grouping of data points in k number of clusters.The algorithm will make sure it has completely grouped the data points into correct clusters, if the centroids (k values) in k-means remains same place or in point for 2 iteration .