I was wondering if it was possible to have a way to sort text rows in a specific manner. What I mean by that is, imagine we have a column of 15 rows which could contain :
Foo
Bar
Something
Other_example
We want to be able to sort them in this particular order. The easy option I found was to put numbers in front of them (1 - Foo, 2 - Bar, etc) and then sorting them in a normal (alphanumerical) manner, but that is not really visually appealing, I would say.
Is there another way to do it simply ? For example by "hiding" the numbers, or something else ? Of course I could write a script for it with with a condition such as a switch-case, but that wouldn't be truly what I am looking for and easily done within the spreadsheet itself (I think so at least, I have never really gone far in sheets possibilities). However if there is no other option, I will do it and add a simple button to access the script, I guess.
Thank for your time !
Sanimys
=ARRAYFORMULA(ARRAY_CONSTRAIN(SORT(IFERROR(
VLOOKUP(C2:C, {A2:A, ROW(A2:A)}, {1, 2}, 0)), 2, 1), 999^99, 1))
Related
In our schools, we have books of the same title by the same author but different ISBN #s. I am working on an inventory list so that we can scan the different ISBNs and then find out what is on hand for a title.
Here is my working spreadsheet demo. The live version will be separated (columns A-D by data that comes in on another sheet (possibly by Google Forms) and a separate sheet (F-J) that does all the math. For convenience / testing, they are all on one sheet.
Essentially, in column F, I would like to sum all the quantities in A where the ISBN's in C match any of the values of G and place it in F.
The formula I am using in F doesn't seem to completely work:
=SUMIF(C:C,arrayformula(split(G2,",")),A:A)
It captures the first match but ignores / doesn't loop over the rest. I have looked at Sumifs and Match and I cannot seem to get any closer with the syntax. I would greatly appreciate if anyone can help me solve this dilemma.
Additionally, I know how to do this with a custom script but I need to avoid that as end users break things for one reason or another and I can't handle the debugging load the way this could possibly be deployed.
Thanks in advance for anyone willing to take a look at this!
~Allan
Try in F2
=sum(query(A:D,"select A where C matches '"& textjoin("|",,split(G2,",")) &"' ",0))
delete everything in F2:F & J2:J and use F2:
=INDEX(IF(G2:G="",,MMULT(IFERROR(VLOOKUP(SPLIT(G2:G, ","), {C:C, A:A}, 2, ), 0),
SEQUENCE(COLUMNS(SPLIT(G2:G, ",")), 1, 1, ))))
in J2 use:
=ARRAYFORMULA(IF(G2:G="",,F2:F*I2:I))
I have a matrix consisting of 3 rows and 4 columns of which which I require the central two columns.
I have attempted extracting the central two columns as follows:
a = a[[2 ;; 3, All]];
On the mathematica function list, the first entry in a[[2 ;; 3, All]] represents the rows and the second the columns, however whenever I try a[[All,2 ;; 3]] it removes the top row rather than the two columns. For some reason they seem inverted. I tried going around this by switching the entries around however, when I use a[[2 ;; 3, All]], I get the error: Part: Cannot take positions 2 through 3 in a.
I cannot wrap my head around why this keeps happening. It also refuses to extract single columns from the matrix as well.
You show that you are assigning a variable to itself and then saying that things don't work for you. That makes me think you might have previously made assignments to variables and the results of that are lurking in the background and might be responsible for what you are seeing.
With a fresh start of Mathematica, before you do anything else, try
mat={{a,b,c,d},
{e,f,g,h},
{i,j,k,l}};
take23[row_]:=Take[row,{2,3}];
newmat = Map[take23, mat]
Map performs the function take23 on every row and returns a list containing all the results giving
{{b,c},
{f,g},
{j,k}}
If need be you can abbreviate that to
newmat = Map[Take[#,{2,3}]&, mat]
but that requires you understand # and & and it gives the same result.
If necessary you can further abbreviate that to
newmat = Take[#,{2,3}]& /# mat
Map is widely used in Mathematica programming and can do many more things than just extract elements. Learning how to use that will increase your Mathematica skill greatly.
Or if you really need to use ;; then this
newmat = mat[[All, 2;;3]]
I interpret the documentation for that to mean you want to do something with All the rows and then within each row you want to extract from the second to the third item. That seems to work for me and instantly returns the same result.
If you instead wrote
newmat = mat[[1;;2, 2;;3]]
that would tell it that you wanted to work from row 1 down to row 2 and within those you want to work from column 2 to column 3 and that gives
{{b,c},
{f,g}}
Question
For the data below, is there a way to return results —for each order in col B— either:
If the most recent status [col D] for an order (ex. for order 10021) is closed, then return that row.
If not, return every row since the most recent closed status for that order (ex. for order 10020, rows 4 and 5).
Previous efforts and attempted solutions
Previously, I was only returning one result, the most recent status for each order with the following:
=SORTN(SORT(A2:D,1,FALSE),9^9,2,2,FALSE)
However, I would like if orders can have more than one current status.
I've tried a few things, and was able to achieve what I'm looking for, unfortunately only if there is one order, with the following:
(The linked sheet below explains how I got to this)
=IFERROR(FILTER(A2:D5,A2:A5>INDEX(SORT(FILTER(A2:D5,D2:D5="CLOSED"),1,0),1,1)),FILTER(A2:D5,A2:A5>=INDEX(SORT(FILTER(A2:D5,D2:D5="CLOSED"),1,0),1,1)))
The other alternative I can think of is a script with a loop.
Summary
It was difficult to know how to title this question but came to it since essentially we're trying to filter for the unique of col B, with conditions against col A & D.
Here's a link to a sample Google spreadsheet you can edit, showing all the attempts.
All your help and comments are greatly appreciated!
maybe like this:
=ARRAYFORMULA(UNIQUE(SORT({VLOOKUP(UNIQUE(INDIRECT("B2:B"&COUNTA(B2:B)+1)),
SORT({B2:B, TO_TEXT(A2:D)}, 2, 0), {2, 3, 4, 5}, 0);
FILTER(A2:D, D2:D="RETURN")},1,1)))
Solution
All credit to Matt King who found a complete answer.
=ARRAYFORMULA(QUERY({A:D,(COUNTIFS(C:C,C:C,A:A,">="&A:A)=1)*(D:D="CLOSED")
+NOT(REGEXMATCH(TRIM(TRANSPOSE(QUERY(IF((TRANSPOSE(A:A)<=A:A)*(TRANSPOSE(C:C)=C:C),D:D,)
,,9^99))),"CLOSED"))},"select Col1,Col2,Col3,Col4 where Col5=1"))
Essentially,
First assigning a count to each row for any given order
Transpose and combine statuses
If there is a CLOSED status in there, don't use it
Then filter with query language
Resulting in—
See solution here.
Mod
I added a clause to completely exclude the status NOTE from current records—
=ARRAYFORMULA(QUERY({A:D,(COUNTIFS(B:B,B:B,A:A,">="&A:A)=1)*(D:D="CLOSED")+
(ARRAYFORMULA(IF((ARRAYFORMULA(NOT(REGEXMATCH(TRIM(TRANSPOSE(QUERY
(IF((TRANSPOSE(A:A)<=A:A)*(TRANSPOSE(B:B)=B:B),D:D,),,9^99))),"CLOSED"))))
=TRUE,IF((ARRAYFORMULA(NOT(TRANSPOSE(ARRAYFORMULA(TRANSPOSE(D:D)))="NOTE")))
=FALSE,FALSE,TRUE),FALSE)))},"select Col1,Col2,Col3,Col4 where Col5=1"))
Implementation
This was sample tested against 2500 rows of data, and took over 80 seconds to execute. So although this answers the question, it isn't necessarily a viable solution.
Having a bit of an issue and unsure if it's actually possible to do.
I'm working on a file that I will enter target progression vs actual target reporting the % outcome.
PAGE 1
¦NAME ¦TAR 1 %¦TAR 2 %¦TAR 3 %¦TAR 4 %¦OVERALL¦SUB 1¦SUB 2¦SUB 3¦
¦NAME1¦ 114%¦ 121%¦ 100%¦ 250%¦ 146%¦ 2¦ 0¦ 0%¦
¦NAME2¦ 88%¦ 100%¦ 90%¦ 50%¦ 82%¦ 0¦ 1¦ 0%¦
¦NAME3¦ 82%¦ 54%¦ 64%¦ 100%¦ 75%¦ 6¦ 6¦ 15%¦
¦NAME4¦ 103%¦ 64%¦ 56%¦ 43%¦ 67%¦ 4¦ 4¦ 24%¦
¦NAME5¦ 87%¦ 63%¦ 89%¦ 0%¦ 60%¦ 3¦ 2¦ 16%¦
Now I already have it sorting all rows by the Overall % column so I can quickly see at a glance but I am creating a second page that I need to reference points.
So on the second page I would like to somehow sort and reference different columns for example
PAGE 2
TOP TAR 1¦Name of top %¦Top %¦
TOP TAR 2¦Name of top %¦Top %¦
Is something like this possible to do?
Essentially I'm creating an Employee of the Month form that automatically works out who has topped what.
I'm willing to drop a paypal donation for whoever can figure this out for me as I've been doing it manually every month and would appreciate the time saved
I don't think a complicated array formula is necessary for this - I am suggesting a fairly standard Index/Match approach.
First set up the row titles - you can just copy and transpose them from Page 1, or use a formula in A2 of Page 2 like
=transpose('Page 1'!B1:E1)
The use them in an index/match to get the data in the corresponding column of the main sheet and find its maximum (in C2)
=max(index('Page 1'!A:E,0,match(A2,'Page 1'!A$1:E$1,0)))
Finally look up the maximum in the main sheet to find the corresponding name:
=index('Page 1'!A:A,match(C2,index('Page 1'!A:E,0,match(A2,'Page 1'!A$1:E$1,0)),0))
If you think there could be a tie for first place with two or more people getting the same score, you could use a filter to get the different names:
So if the max score is in B8 this time (same formula)
=max(index('Page 1'!A:E,0,match(A8,'Page 1'!A$1:E$1,0)))
the different names could be spread across the corresponding row using transpose (in C8)
=ArrayFormula(TRANSPOSE(filter('Page 1'!A:A,index('Page 1'!A:E,0,match(A8,'Page 1'!A$1:E$1,0))=B8)))
I have changed the test data slightly to show these different scenarios
Results
I'm trying to figure out what is the most efficient way to parse data from a file using Lua. For example lets say I have a file (example.txt) with something like this in it:
0, Data
74, Instance
4294967295, User
255, Time
If I only want the numbers before the "," I could think of a few ways to get the information. I'd start out by getting the data with f = io.open(example.txt) and then use a for loop to parse each line of f. This leads to the heart of my question. What is the most efficient way to do this?
In the for loop I could use any of these methods to get the # before the comma:
line.find(regex)
line:gmatch(regex)
line:match(regex)
or Lua's split function
Has anyone run test for speed for these/other methods which they could point out as the fast way to parse? Bonus points if you can speak to speeds for parsing small vs. large files.
You probably want to use line:match("%d+").
line:find would work as well but returns more than you want.
line:gmatch is not what you need because it is meant to match several items in a string, not just one, and is meant to be used in a loop.
As for speed, you'll have to make your own measurements. Start with the simple code below:
for line in io.lines("example.txt") do
local x=line:match("%d+")
if x~=nil then print(x) end
end