Forum Discussion

RMF40's avatar
RMF40
Copper Contributor
Oct 01, 2024

How do I change a table with 2 columns where I have repeating values in both columns into a matrix?

Hopefully I will be able to explain my problem correctly.

 

I have a table with two columns in it. Column A has students in it, column B has the subject that each student is taking. Both column A and column B have repeating values, but together they are unique. For example

 

NameSubject
JimmyMaths
JimmyBiology
JimmyChemistry
MaximeMaths
MaximeComputer Science
MaximeHistory

 

What I need to do is turn this into a matrix (is that the correct term?) which looks like this

 

NameSubject ASubject BSubject C
JimmyMathsBiologyChemistry
MaximeMathsComputer ScienceHistory

 

Can this be done?

  • djclements's avatar
    djclements
    Bronze Contributor

    RMF40 If you have Excel for Microsoft 365, you could try something along these lines (using the new PIVOTBY function):

     

    =LET(
        a, FILTER(A2:B1000,A2:A1000<>""),
        r, CHOOSECOLS(a,1),
        v, CHOOSECOLS(a,2),
        n, ROWS(r),
        c, "Subject "&CHAR(MMULT((SEQUENCE(n)>=SEQUENCE(,n))*(r=TOROW(r)),EXPAND(1,n,,1))+64),
        PIVOTBY(r,c,v,CONCAT,0,0,,0)
    )

     

    See attached...

    • RMF40's avatar
      RMF40
      Copper Contributor

      nduhiye2018 that was my initial thought, but the pivot table keeps putting totals into the cells rather than the subject choices. 

  • RMF40 

    As variant that could be Power Query

    let
        Source = Excel.CurrentWorkbook(){[Name="Students"]}[Content],
        GroupNames = Table.Group(
            Source, {"Name"},
            {
                {"Subject", each List.Sort( [Subject] )}
            }),
        SubjectNames = List.Transform(
            {1..List.Max( Table.TransformColumns(
                GroupNames,
                {"Subject", (q) => List.Count(q)} )[Subject] )},
                (e) => "Subject " & Character.FromNumber(e+64)
            ),
        ExtractSubjects = Table.TransformColumns(
            GroupNames,
            {"Subject", each Text.Combine(List.Transform(_, Text.From), ","), type text}
        ),
        SplitSubjects = Table.SplitColumn(
            ExtractSubjects,
            "Subject",
            Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), SubjectNames)
    in
        SplitSubjects

    Please check attached.

  • Lorenzo's avatar
    Lorenzo
    Silver Contributor

    RMF40 

    A Power Query variant attached:

    let
        Source = TableSource,
        GroupedName = Table.Group(Source, {"Name"},
            {
                {"DATA", each
                    Table.Transpose(
                        Table.SelectColumns(_, {"Subject"})
                    ),
                    type table
                },
                {"Count", Table.RowCount, Int64.Type}
            }
        ),
        RemovedCount = Table.RemoveColumns(GroupedName, {"Count"}),
        SortedName = Table.Sort(RemovedCount, {{"Name", Order.Ascending}}),
        ListMaxCount = { 1..List.Max( GroupedName[Count] ) },
        ExpandedSubject = Table.ExpandTableColumn(SortedName, "DATA",
            List.Transform( ListMaxCount, each "Column" & Text.From(_) ),
            List.Transform( ListMaxCount, each "Subject " & Character.FromNumber(_ +64) )
        )
    in
        ExpandedSubject

     

     

  • RMF40 

    All you are trying to do is generated a list of subjects for each student.  Unfortunately the current implementation of Excel will simply return an error message "Nested arrays are not supported".  Not very helpful when the whole purpose of the calculation is to return a nested array"!  A possible solution is to use

    =LET(
        student,      UNIQUE(Name),
        SubjectListλ, LAMBDA(n, TOROW(FILTER(Subject, Name = n))),
        subjectList,  MAPλ(student, SubjectListλ),
        SORT(HSTACK(student, subjectList))
    )

    The first line creates a list of distinct student names.  The second line defines a function that will return a list of subjects for any given student.  The third line uses MAP to return the subject list for each student in turn.  This is where the Excel in-built functionality fails.  What I have done instead is use a function MAPλ that I wrote to overcome the problem.  The final line sorts the data alphabetically by student name, to give

     

     

    It is complicated but the user need never look at it!

     

Resources