I've been browsing multiple different places to try and find an answer but I think I'm likely too thick and/or over simplifying how Excel works.
What I'm trying to get is hopefully a matrix, unless there is a better way where I can see in this example, how many times a product has been bought on the same day, by the same customer together with another product.
This is what the data looks like:
A | B | C | |
---|---|---|---|
1 | Client Name | Booking Date | Product Name |
2 | John | 2/26/2024 | Product 1 |
3 | John | 2/26/2024 | Product 1 |
4 | John | 2/26/2024 | Product 2 |
5 | John | 2/26/2024 | Product 3 |
6 | John | 2/26/2024 | Product 4 |
7 | John | 3/30/2024 | Product 1 |
8 | John | 4/11/2024 | Product 2 |
9 | John | 4/11/2024 | Product 3 |
10 | Dave | 6/24/2024 | Product 3 |
11 | Dave | 6/24/2024 | Product 1 |
12 | Dave | 6/24/2024 | Product 3 |
13 | Dave | 6/24/2024 | Product 1 |
14 | Dave | 7/17/2024 | Product 2 |
15 | Dave | 7/17/2024 | Product 1 |
16 | Bob | 6/6/2024 | Product 1 |
17 | Bob | 6/6/2024 | Product 2 |
18 | Bob | 6/8/2024 | Product 2 |
19 | Bob | 6/8/2024 | Product 3 |
I've tried to implement various countifs and xlookups to no real avail, and I'm starting to think I'm asking too much.
This is how I expect the outcome to be:
1 | Product 1 | Product 2 | Product 3 | Product 4 | |
---|---|---|---|---|---|
2 | Product 1 | 2 | 3 | 2 | 1 |
3 | Product 2 | 3 | 0 | 3 | 1 |
4 | Product 3 | 2 | 3 | 1 | 1 |
5 | Product 4 | 1 | 1 | 1 | 0 |
Explanation of the outcome for Product 2:
1st buy:
John 2/26/2024 together with: Product 1 (twice, but counts as 1x together), not together with Product 2 (it needs to be more than 1 of itself to count as together with), together with Product 3 and together with Product 4.
This counts as {1,0,1,1}.
2nd buy:
John 4/11/2024 together with: Product 1, no; Product 2; no, Product 3, yes, Product 4, no.
This counts as {0,0,1,0}.
3rd buy:
Dave 7/17/2024 together with: Product 1, yes; Product 2, no, 3 & 4, no.
This counts as {1,0,0,0}.
4th buy:
Bob 6/6/2024 together with: 1, yes; 2, no; 3, no; 4, no.
This counts as {1,0,0,0}.
5th (last) buy:
Bob 6/8/2024 together with: 1, no; 2, no; 3, yes; 4, no.
This counts as {0,0,1,0}.
Summed by column (product) makes: {3,0,3,1}
Any way around this that isn't overtly complex, does this request make sense?? Thank you!
It's possible, but not easy (thanks for the challenge!):
=LET(data,A2:C19, ab,TAKE(data,,1)&INDEX(data,,2), c,DROP(data,,2), u,UNIQUE(c),
REDUCE(HSTACK("",TOROW(u)), u,
LAMBDA(d,e,
LET(f,FILTER(HSTACK(data,ab),ISNUMBER(XMATCH(ab,FILTER(ab,c=e)))),
r,IFNA(REDUCE(0, UNIQUE(INDEX(f,,4)),
LAMBDA(x,y,
LET(z,FILTER(INDEX(f,,3),INDEX(f,,4)=y),
s,UNIQUE(DROP(SORTBY(z,INDEX(z,,1)<>e),1)),
VSTACK(x,
IFERROR(MMULT(SEQUENCE(,ROWS(s),,0),N(s=TOROW(u))),0))))),0),
VSTACK(d,
HSTACK(e, BYCOL(r,SUM)))))))
This loops through the unique products e
, filters name & date & product rows where the product column contains the current product e
.
Next it loops through the unique name & dates and adds 1 to the product's count if it was bought together with current product e
(where 1 bought of e
does not count as together).
I figured this could be simplified (I think) a bit using MAKEARRAY:
=LET(a,A2:A19, b,B2:B19, c,C2:C19, p,UNIQUE(c), n,ROWS(p),
VSTACK(HSTACK("",
TOROW(p)),
HSTACK(p,
MAKEARRAY(n,n,LAMBDA(v,w,
LET(z,INDEX(p,v),
SUM(BYROW(UNIQUE(FILTER(a&b,c=z)),LAMBDA(x,LET(f,FILTER(c,1-ISNA(XMATCH(a&b,x))),SUM(N(IFERROR(UNIQUE(DROP(SORTBY(f,f<>z),1)),"")=INDEX(p,w)))))))))))))
(probably more user friendly:)
=LET(client,A2:A19,
booking,B2:B19,
product,C2:C19,
uniqueproduct,UNIQUE(product),
unqprodrows,ROWS(uniqueproduct),
VSTACK(
HSTACK("",
TOROW(uniqueproduct)),
HSTACK(uniqueproduct,
MAKEARRAY(unqprodrows, unqprodrows,
LAMBDA(verticalcounter, horizontalcounter,
LET(currentrowproduct,INDEX(uniqueproduct,verticalcounter),
SUM( BYROW(UNIQUE(FILTER(client&booking,product=currentrowproduct)),
LAMBDA(nthbuy,
LET(nthbuyfilterincludingself,FILTER(product,1-ISNA(XMATCH(client&booking,nthbuy))),
SUM(
N(IFERROR( UNIQUE(DROP(SORTBY(nthbuyfilterincludingself,nthbuyfilterincludingself<>currentrowproduct),1)) ,"")
=INDEX(uniqueproduct,horizontalcounter)))))))))))))