Product Affinity, How do I find popular pairings?

MistyWind

New Member
Joined
Dec 29, 2020
Messages
13
Office Version
  1. 365
Platform
  1. Windows
I'd like to run a product affinity analysis, meaning I'd like to find out which are the most popular pairings of products customers are buying. My data is structured (shown below) with Order ID in column A and Product ID in column B. How do I identify the most popular pairings while identifying how many times each unique pair has been purchased? I'm not concerned with the quantity of items ordered in each unique order, I just need to know the pairs and the total number of them. Thanks.


Order IDProduct ID
10005612-325
36-125
83-558
45-254
10005745-696
10005836-125
47-122
78-562
10005983-558
33-785
78-191
58-538
56-325
10006083-558
45-254
36-125
 

Excel Facts

Does the VLOOKUP table have to be sorted?
No! when you are using an exact match, the VLOOKUP table can be in any order. Best-selling items at the top is actually the best.
If you're open to VBA, try:

Open a copy of your workbook. Press Alt-F11 to open the VBA editor. Press Alt-IM to Insert a Module. Paste the following code in the window that opens:

VBA Code:
Sub CountPairs()
Dim MyTab As Variant, MyDic As Object, r1 As Long, r2 As Long, k As String

    MyTab = Range("A2:B" & Range("B1").End(xlDown).Row).Value
    Set MyDic = CreateObject("Scripting.Dictionary")
    
    For r1 = 1 To UBound(MyTab)
        For r2 = r1 + 1 To UBound(MyTab)
            If MyTab(r2, 1) <> "" Then Exit For
            k = IIf(MyTab(r1, 2) > MyTab(r2, 2), MyTab(r2, 2) & " / " & MyTab(r1, 2), MyTab(r1, 2) & " / " & MyTab(r2, 2))
            MyDic(k) = MyDic(k) + 1
        Next r2
    Next r1
    
    Range("D1:E1").Value = Array("Pair", "Count")
    Range("D2").Resize(MyDic.Count).Value = WorksheetFunction.Transpose(MyDic.keys)
    Range("E2").Resize(MyDic.Count).Value = WorksheetFunction.Transpose(MyDic.items)
    
    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add Key:=Range("E2"), Order:=xlDescending
        .SetRange Range("D1:E" & MyDic.Count + 1)
        .Header = xlYes
        .Orientation = xlTopToBottom
        .Apply
    End With
End Sub

This assumes that your orders and parts are in columns A:B, and the results will be displayed in columns D:E.

The results of this macro on your sample are these:

Book1
ABCDE
1Order IDProduct IDPairCount
210005612-32536-125 / 83-5582
336-12536-125 / 45-2542
483-55845-254 / 83-5582
545-25412-325 / 36-1251
610005745-69612-325 / 83-5581
710005836-12512-325 / 45-2541
847-12236-125 / 47-1221
978-56236-125 / 78-5621
1010005983-55847-122 / 78-5621
1133-78533-785 / 83-5581
1278-19178-191 / 83-5581
1358-53858-538 / 83-5581
1456-32556-325 / 83-5581
1510006083-55833-785 / 78-1911
1645-25433-785 / 58-5381
1736-12533-785 / 56-3251
1858-538 / 78-1911
1956-325 / 78-1911
2056-325 / 58-5381
Sheet1


Let us know how this works for you.
 
Upvote 1
If you're open to VBA, try:

Open a copy of your workbook. Press Alt-F11 to open the VBA editor. Press Alt-IM to Insert a Module. Paste the following code in the window that opens:

VBA Code:
Sub CountPairs()
Dim MyTab As Variant, MyDic As Object, r1 As Long, r2 As Long, k As String

    MyTab = Range("A2:B" & Range("B1").End(xlDown).Row).Value
    Set MyDic = CreateObject("Scripting.Dictionary")
   
    For r1 = 1 To UBound(MyTab)
        For r2 = r1 + 1 To UBound(MyTab)
            If MyTab(r2, 1) <> "" Then Exit For
            k = IIf(MyTab(r1, 2) > MyTab(r2, 2), MyTab(r2, 2) & " / " & MyTab(r1, 2), MyTab(r1, 2) & " / " & MyTab(r2, 2))
            MyDic(k) = MyDic(k) + 1
        Next r2
    Next r1
   
    Range("D1:E1").Value = Array("Pair", "Count")
    Range("D2").Resize(MyDic.Count).Value = WorksheetFunction.Transpose(MyDic.keys)
    Range("E2").Resize(MyDic.Count).Value = WorksheetFunction.Transpose(MyDic.items)
   
    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add Key:=Range("E2"), Order:=xlDescending
        .SetRange Range("D1:E" & MyDic.Count + 1)
        .Header = xlYes
        .Orientation = xlTopToBottom
        .Apply
    End With
End Sub

This assumes that your orders and parts are in columns A:B, and the results will be displayed in columns D:E.

The results of this macro on your sample are these:

Book1
ABCDE
1Order IDProduct IDPairCount
210005612-32536-125 / 83-5582
336-12536-125 / 45-2542
483-55845-254 / 83-5582
545-25412-325 / 36-1251
610005745-69612-325 / 83-5581
710005836-12512-325 / 45-2541
847-12236-125 / 47-1221
978-56236-125 / 78-5621
1010005983-55847-122 / 78-5621
1133-78533-785 / 83-5581
1278-19178-191 / 83-5581
1358-53858-538 / 83-5581
1456-32556-325 / 83-5581
1510006083-55833-785 / 78-1911
1645-25433-785 / 58-5381
1736-12533-785 / 56-3251
1858-538 / 78-1911
1956-325 / 78-1911
2056-325 / 58-5381
Sheet1


Let us know how this works for you.
Thank you for introducing me to VBA. I haven't used it before. I ran the code as instructed and ran into an error. Here's a screenshot of the debug. I don't know if the error occurred because of format differences than I provided at first. 1) different column header names 2) every line in the order column is populated 3) the product IDs have different character formatting.

Do you know why the code failed? Thanks.

1685627144642.png
 
Upvote 0
First of all, good job in figuring out how to run the macro, I see that I neglected to finish the instructions. There are a few ways to run the macro, you can press F5 from within the editor, or go back to the Excel sheet, press Alt-F8, select CountPairs, and click Run.

The probable reason you got the error is due to having all the order numbers instead of blank lines (your issue 2). My macro looked for the blank lines. To fix that, just change this line:

VBA Code:
            If MyTab(r2, 1) <> "" Then Exit For

to

VBA Code:
            If MyTab(r2, 1) <> MyTab(r1, 1) And MyTab(r2, 1) <> "" Then Exit For

It'll work either way now.

Another possible issue could arise based on the number of product numbers you have. How many product numbers do you have? If you have 1000 items, the number of possible pairs is 1000*999 = 999,000 which is quite a lot. So maybe instead of the whole list, you just want the top 100 pairs? Or do you think that will be an issue?

Your issues 1 and 3 probably won't cause problems. Let me know if this works for you.
 
Upvote 1
Solution
First of all, good job in figuring out how to run the macro, I see that I neglected to finish the instructions. There are a few ways to run the macro, you can press F5 from within the editor, or go back to the Excel sheet, press Alt-F8, select CountPairs, and click Run.

The probable reason you got the error is due to having all the order numbers instead of blank lines (your issue 2). My macro looked for the blank lines. To fix that, just change this line:

VBA Code:
            If MyTab(r2, 1) <> "" Then Exit For

to

VBA Code:
            If MyTab(r2, 1) <> MyTab(r1, 1) And MyTab(r2, 1) <> "" Then Exit For

It'll work either way now.

Another possible issue could arise based on the number of product numbers you have. How many product numbers do you have? If you have 1000 items, the number of possible pairs is 1000*999 = 999,000 which is quite a lot. So maybe instead of the whole list, you just want the top 100 pairs? Or do you think that will be an issue?

Your issues 1 and 3 probably won't cause problems. Let me know if this works for you.
First of all, good job in figuring out how to run the macro, I see that I neglected to finish the instructions. There are a few ways to run the macro, you can press F5 from within the editor, or go back to the Excel sheet, press Alt-F8, select CountPairs, and click Run.

The probable reason you got the error is due to having all the order numbers instead of blank lines (your issue 2). My macro looked for the blank lines. To fix that, just change this line:

VBA Code:
            If MyTab(r2, 1) <> "" Then Exit For

to

VBA Code:
            If MyTab(r2, 1) <> MyTab(r1, 1) And MyTab(r2, 1) <> "" Then Exit For

It'll work either way now.

Another possible issue could arise based on the number of product numbers you have. How many product numbers do you have? If you have 1000 items, the number of possible pairs is 1000*999 = 999,000 which is quite a lot. So maybe instead of the whole list, you just want the top 100 pairs? Or do you think that will be an issue?

Your issues 1 and 3 probably won't cause problems. Let me know if this works for you.
Thank you so much. I didn't make any other changes except for the line of code in the macro. Worked like a charm.
FYI, I'm dealing with just under 500 unique products and over 7,000 rows of order data. Either way this worked just fine. Thank you so much for your help.
 
Upvote 0

Forum statistics

Threads
1,215,170
Messages
6,123,422
Members
449,099
Latest member
COOT

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top