How to pick one of the results of UNIQUE() in Google Sheets - google-sheets

Problem
I have a column with duplicate items in Google Sheets, and I would like to get one of the unique values (say, the last one) in the cell of the formula. Is there a way to do this with just formulas (i.e., no scripts/macros)?
What I've tried
Not sure if this is the best way, but I've tried using the UNIQUE(range) function, which returns a list of distinct values, and I tried to pick one with FILTER(range, condition1, [condition2, …]), but I've only managed to do it when I know in advance and hard-code in the number of unique values.
Since I can get the length of the unique list with =LEN(UNIQUE(my_range)), I tried using the REPT(text_to_repeat, number_of_repetitions) function.
For example,
=REPT(0&";",2) & 1 returns "0;0;1"
but
=FILTER(UNIQUE(A$1:A$26), {REPT(0&";",2) & 1})
(or any variation I tried) doesn't quite work.
P.S.
I realise this is not the most suitable problem for a spreadsheet, and I do wish I was using something like Python, but this is the restriction at the moment.

try:
=QUERY(UNIQUE(A1:A), "offset "&COUNTA(UNIQUE(A1:A))-1)

Or more old-school using index:
=index(unique(A:A),counta(unique(A:A)))
You can also just enter a number fot the one you want e.g.
=index(unique(A:A),2)

Related

Taking Column A values comparing to Column B values if they are the same post to Column C

I'm trying to take the names from column A compare them to the names in column B and then have the similar names get listed in column C.
The problem is these names are automatically updated and out of order, and I need the function in column C to update with them. Also, the names will not be in order, this is why I can't use A=B function. The picture shown is an example of what the solution would look like or something similar. After completing this, I would like to continue using the same function to break down the name data even more. Watched a lot of videos on this, can't find anything specific enough to work.
Side note, I have found a way to do this using different pages within the sheets but not in the same sheet side by side. ex. of what solution
I have tried watching lots of YouTube videos, but nothing goes into detail enough and seem to only explain when similar values are next to each other in column A and B.
This is what I use for 2 different sheets but can't find / understand why when changing values in function to single sheet it wont work:
=filter(Sheet1!A2:B,ISNUMBER(match(Sheet1!A2:A,Raid1!A2:A,0)))
Also, another side note: Can't use True or False. And for uneven number of names in the list ex. Column A has 10 and B has 7 it sorts A for names in B and post similar in C.
Try below formula-
=FILTER(C3:C,INDEX(COUNTIFS(D3:D,C3:C))>0)
You can use VLOOKUP to check common values between columns and store them in another column.
=IFERROR(VLOOKUP(A:A,B:B,1,false),"")
Although this will create gaps in the output column. you can get rid of it by by simply using a filter or so.
all you need is:
=FILTER(C3:C; COUNTIFS(D3:D; C3:C))

Converting a multi column range into one column

I have an instance where I would love to be able to get a column of all the unique names in a range. The problem I am having is that the range is multicolumn.
Let's assume my data is in A1:B3
This works fine if I do:
=unique({A1:A3;B1:B3;C1:C3})
But if that range is named and I do
=unique(NamedRange) or =unique(A1:C3)
Then it will spill over the column. Worse if I want to filter or sort the results in the same formula and then run into errors because the formulas want single column/row or the rows/columns don't match anymore.
I don't deal with named ranges a lot, but I did just make a formula today that had 10 columns in it that I stuck into a range like that so that I could do a complex (for me) filter that gave me the difference of two different ranges, similar to: =FILTER({B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}, NOT(COUNTIF(H5:H, {B4:B93;C4:C93;D4:D93;E4:E93;F4:F93}))). I would REALLY love if I could clean that up and make that messy set B4:F instead.
Is there any formula level function that could stick these all in one column?
Usually I am looking to do other things with it like sort and filter and the multiple columns get even messier.
Thanks for your time. I DID try searching for this, but I could not seem to find the answer.
Use FLATTEN:
=UNIQUE(FLATTEN(A1:C3))
or
=UNIQUE(FLATTEN(NamedRange))

Use Unique in a Filter formula

I have a list of identifiers and a value for each identifier which is filled automatically.
I want to filter the list so I will only get unique identifiers and their respective value.
e.g. "Dana" can appears 3 times but in the filtered table I only want to see the name (and the value) once.
Ideally I'd like to use something like
=filter(a:b,unique(a:a) which obviously doesn't work.
As mentioned, the list updates automatically so a formula that needs to be dragged won't do the trick.
Note: It can be solved by extracting uniques from col A
=unique(A:A)
and then an Arrayformula + vLookup
=arrayformula(if(I1:I>0,vlookup(I1:I,A:B,2,0),""))
but I'm curious to see if it can be solved using Filter for more elegance.
Here's an example (including the solution I mentioned):
https://docs.google.com/spreadsheets/d/1heKdV3U6mdGYkHCIWkeUyqo6AfhgV7ItSmolibH7ecU/edit?usp=sharing
Please use the following
=UNIQUE(A:B)
UPDATE
Following OP's comment/request:
Nice fix! Out of curiosity - is it possible to still use it with the filter function (for example, if I wanted to filter by Col B or add other restrictions) ?
Sure. Try these ones out
=UNIQUE(FILTER(A:B,B:B=333))
OR
=FILTER(UNIQUE(A:B),UNIQUE(B:B)=333)
Reference:
UNIQUE

ARRAYFORMULA with IMPORTRANGE

In column B are listed IDs of Google Sheets. In column C are listed cells, from which I want to import data.
Screenshot of the table
In column D is shown the result of using IMPORTRANGE() by simply dragging it. e.g. for D1 it looks like:
=IMPORTRANGE(B1;C1)
for D2:
=IMPORTRANGE(B2;C2)
and so on.
In column E I want to display the same result but using ARRAYFORMULA that looks like:
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4))
but the function displays only the data from the first spreadsheet.
People complain about this permissions issue a lot, but it's not hard to solve. What I do is have a sheet which I name "Splash sheet" into which I paste the URLs of the documents I wish to link. To its right is a column headed "permit to connect" which contains IMPORTRANGE formulas importing a single cell from each sheet -- usually a cell containing a confirmation code, number or document name -- on a sheet also named "Splash Sheet." For example,
=IF(B3="enter URL",,CONCATENATE(IMPORTRANGE(B3,"Splash sheet!A1")," ",IMPORTRANGE(B3,"Splash sheet!B1")))
So, when you first connect a spreadsheet via its URL, you get those messages telling you you need to connect, you click the Permit Access, the confirmation code/number/document name appears in the second column, and voilá, your sheets are connected forevermore! Now all your other IMPORTRANGEs referencing that URL will work, and you can use IMPORTRANGE formulas that reference the URL-containing cells on the "splash sheet."
As for the OP's original question, I came here seeking an answer to the same problem, and after more research have realized that we are attempting the impossible here. No way to do this an ARRAYFORMULA. No way around writing formulas that reference every single cell a document's URL may go into.
Problem is you can't make arrays of arrays in spreadsheets; that would involve multiple dimensions, and the medium is inherently two-dimensional. This is what people use databases for.
ARRAYFORMULA doesn't work when importing data (I think it relates to permissions). You could use something like this, =IFERROR(IMPORTRANGE(B5:B7;C5:C7)) and pre-fill the column first, but still there would be the permissions issue. Each new imported sheet needs it's permissions granted by a user.
TLDR: If I understand your intention correctly when you say you would like to see
=ARRAYFORMULA(IMPORTRANGE(B2:B4,C2:C4)), I believe you can make that
happen using the following.
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
Breakdown
Use IMPORTRANGE with INDIRECT to create ranges inside ARRAYFORMULA
Call INDIRECT with the ADDRESS function
Call ADDRESS with the ROW and COLUMN functions since they take ranges via ARRAYFORMULA
using IMPORTRANGE with INDIRECT
IMPORTRANGE's two parameters are the spreadsheet url stored in B2:B4 for this example and the range (e.g. sheet!A1:B2) stored in C2:C4.
Since IMPORTRANGE doesn't take a range reference directly as you mentioned, you'll need to build it for each row with ARRAYFORMULA using the INDIRECT function.
INDIRECT can be used to compose a cell reference using A1 notation, for instance
=IMPORTRANGE(INDIRECT("B" & 2), INDIRECT("C" & 2))
will produce the same result as
=IMPORTRANGE(B2, C2)
Since this produces the same result, we now just have to find a way to make INDIRECT work with ARRAYFORMULA
Use ADDRESS to build the parameters for INDIRECT
Next you want to use ADDRESS to build the A1 reference for INDIRECT. For the current purposes, ADDRESS takes a numerical value for row and column as parameters
=INDIRECT(ADDRESS(2,2))
will produce the same result as
=INDIRECT("B" & 2)
Since these two are interchangeable, now we just need to find a way to get the numerical row and column values out of ARRAYFORMULA.
Call ADDRESS using the ROW and COLUMN functions
From there, you can get the row and column indexes from standard A1 notation using the ROW and COLUMN functions. While this may seem like we're pointlessly going in circles, the difference now is that ROW and COLUMN perform as expected with the ranges provided by ARRAYFORMULA. So given that ADDRESS will return $B$2 using using either method below
=ADDRESS(2,2)
or
=ADDRESS(ROW(B2),COLUMN(B2))
we now know that
=ARRAYFORMULA(ADDRESS(ROW(B2:B4),COLUMN(B2:B4)))
will produce the following array of addresses
{ $B$2; $B$3; $B$4 }
Final Assembly
So when we put this all together, we get
=ARRAYFORMULA(IMPORTRANGE(
INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)),
INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4))
)
where INDIRECT(ADDRESS(ROW(B2:B4), COLUMN(B2:B4)) is more or less interchangeable with what you might expect from B2:B4 inside ARRAYFORMULA and represents the url parameter
and INDIRECT(ADDRESS(ROW(C2:C4), COLUMN(C2:C4)) is roughly interchangeable with what you might expect from C2:C4 inside ARRAYFORMULA and represents the range parameter.
Suggestions on organization
I recommend using the indentation (Alt +Enter to create a new line ) above along with your indentation of choice to keep it easier to read. In the end it's just a bit more syntactic sugar and if spaces are used well it shouldn't be much harder to understand and make changes to 6 months later.
RE: Permissions - as mentioned by Atiq Zabinski, just placing a simple
IMPORTRANGE("http:/xxxx", "A1") somewhere on the sheet will provide a
means to know if the sheet is connected or not and the error message
should give you a context menu for connecting the sheet. You'll might
want to stay away from error handling in these scenarios as it will
slow down the process of connecting the sheets.

Google Spreadsheet range names

In Google Docs Spreadsheets, one can use Range Names to put labels on ranges of cells to make formulas more legible. In most formulas, one can use the range C:C to denote the entire C column, and C2:C to denote the entire C column after and including C2.
Is there a way to create range names of the same nature? When I try C:C or C2:C or Sheet!C:C or 'Sheet'!C:C I always get the error "The range you specified is not in a valid range format." I would like the range name to expand as my form adds rows to my spreadsheet. Thanks.
I just discovered the if you use the '-' operator, it starts from the bottom row. So,
=INDIRECT("-D:D12")
starts from the last row and works it's way up to D12!
I had a similar problem. Although I do not know how to do exactly what you are asking, you can do essentially the same thing by referencing cells that are not yet created.
For example:
Column C currently has 100 cells (100 rows in the sheet)
Instead of referencing it with C:C, use C1:C999
If you make the row reference high enough, then you can account for future rows that you will create. Hope it helps.
I don't think so... even if you select a column manually while in the Range Name selector, it complains. That would be a nice feature and it would make sense since they support column ranges for formulas already.
I believe this does work now. I have a range name of "Sheet1!A10:AW10" with no problems.
If you try to do a whole column, I think it will just take all the available cells in the column at that time. i.e. if you make more cells later, you need to manually add to the range name.
I had the same problem with ranges such as A3:A which normally work in other places such as ARRAYFORMULA(), but the workaround is to not specify the starting row, such as A:A. In cases when this would be a problem, you can proxy the data through another column using something like ARRAYFORUMULA(A25:A) as the formula.
Update: Apparently I haven't read the question properly. I see that the OP had tried leaving out the row number, so perhaps it wasn't working at that time, but it does now. The notations still don't work.
Update2: I didn't notice that google spreadsheet replaces ranges like A:A to A1:A50, so new rows added later on do not still get included. That I think is what #Dean is trying to say in his answer.
I think it's a helpful tool to use Insert -> Define new range to make a wizard appear and make the syntax correct. Hehe
My response in other topic

Resources