I have a dataset (Excel) with the results of customer satisfaction questionnaires over several years.
The questions in the Excel are each a column, and every row is the value of the response (value 1 to 5).
However, those questions are separated in categories (eg. questions about "communication", "quality",...).
I'd like to find a way to have these columns "grouped" or "categorized" into categories, but can't wrap my head around it. It felt like a thing to do with hierarchies but that is clearly not the way to go.
UPDATED with sample data:
Image of excel data
Quality performance
Company perception
Communication
Quality Q1 Quality Q2 Quality Q3
Company Q1 CompanyQ2
Response Time Correct Capable
Responder
Quality Q1
Quality Q2
Quality Q3
Company Q1
CompanyQ2
Response Time
Correct Capable
Client 1
0
0
5
0
5
1
2
Client 2
2
5
5
3
1
4
3
Client 3
5
1
3
5
4
3
3
Client 4
0
4
2
4
0
2
4
Client 5
0
1
5
2
3
0
5
Client 6
5
2
0
0
0
2
3
Client 7
2
1
4
1
1
2
3
Client 8
4
0
2
0
5
4
5
Client 9
2
0
2
1
1
0
5
Client 10
1
2
4
4
0
2
3
Client 11
2
4
5
4
3
0
0
On PowerBI I'd like to have a score per category on which I can drill down to get into deeper detail.
You can try this
let
Source = Table.FromRows(
Json.Document(
Binary.Decompress(
Binary.FromText(
"ZZC7DoQgEEV/xVBbyMi+ar/AbY2FcSlIFIxisX+/qwzmisWEucPJnUfTiLdeJmc/eha5qNduMP6b1RIFoSj/onLj1FnGDkFBjKs1feeNs1mwXvTlo3LzrHsv2rwR1WC09dlmVXDc4N3qhCDthfC5RcmQ2nMAS3CIueL8BCpup9g56pADGOeS7EbsFmYF8A5AAUFp6wcX4wLy2DgBn8lc8Twqbf0CgMDxMqMsoJdK7E+9JVJ4xbBW2/4A",
BinaryEncoding.Base64
),
Compression.Deflate
)
),
let
_t = ((type nullable text) meta [Serialized.Text = true])
in
type table [
Column1 = _t,
#"Quality performance" = _t,
Column3 = _t,
Column4 = _t,
#"Company perception" = _t,
Column6 = _t,
Communication = _t,
Column8 = _t
]
),
ct = Table.TransformColumnTypes(
Source,
{
{"Column1", type text},
{"Quality performance", type text},
{"Column3", type text},
{"Column4", type text},
{"Company perception", type text},
{"Column6", type text},
{"Communication", type text},
{"Column8", type text}
}
),
DH = Table.DemoteHeaders(ct),
CT = Table.TransformColumnTypes(
DH,
{
{"Column1", type text},
{"Column2", type text},
{"Column3", type text},
{"Column4", type text},
{"Column5", type text},
{"Column6", type text},
{"Column7", type text},
{"Column8", type text}
}
),
KFR = Table.FirstN(CT, 1),
TT = Table.Transpose(KFR),
AC = Table.AddColumn(
TT,
"Custom",
each
if [Column1] = "Column1" then
ct[Column1]{0}
else if Text.Contains([Column1], "Column") then
null
else
[Column1]
),
RTR = Table.Skip(AC, 1),
FD = Table.FillDown(RTR, {"Custom"}),
#"Promoted Headers" = Table.PromoteHeaders(ct, [PromoteAllScalars = true]),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(
#"Promoted Headers",
{"Responder"},
"Attribute",
"Value"
),
#"Grouped Rows" = Table.Group(
#"Unpivoted Other Columns",
{"Responder"},
{{"ad", each _, type table [Responder = nullable text, Attribute = text, Value = text]}}
),
#"Added Custom" = Table.AddColumn(
#"Grouped Rows",
"Custom",
each
let
src = [ad],
Index = Table.AddIndexColumn(src, "Index", 0, 1),
Add = Table.AddColumn(Index, "Custom", each FD[Custom]{[Index]}),
Remove = Table.RemoveColumns(Add, {"Index"}),
#"Added Custom1" = Table.AddColumn(
Remove,
"Custom.1",
each List.Difference(Text.Split([Attribute], " "), Text.Split([Custom], " "))
),
#"Expanded Custom.1" = Table.ExpandListColumn(#"Added Custom1", "Custom.1"),
#"Renamed Columns" = Table.RenameColumns(
#"Expanded Custom.1",
{{"Custom", "CAT"}, {"Custom.1", "SubCat"}}
),
#"Removed Columns" = Table.RemoveColumns(#"Renamed Columns", {"Attribute"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Columns", {{"Value", type number}})
in
#"Changed Type"
),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom", {"Custom"}),
#"Expanded Custom" = Table.ExpandTableColumn(
#"Removed Other Columns",
"Custom",
{"Responder", "Value", "CAT", "SubCat"},
{"Responder", "Value", "CAT", "SubCat"}
)
in
#"Expanded Custom"
I think the first step is to unpivot your table so you have one row per item following this pattern. Microsoft Docs - Unpivot columns. Will create code something like this:
=Table.UnpivotOtherColumns(Source, {"Responder"}, "Question", "Response")
You can then create a "Question" table with a "Question" column and a "Group". Join the question table to your unpivoted table by the question, and you can now report on your questions and groups.
Related
I have a dataset which has many columns listing multiple years worth of values, example:
Country
2020 Rank X
2020 Rank Y
2021 Rank X
EU
1
2
3
USA
2
3
4
Etc. Each year has about 6 values for each country and there is 4 years of data, approx 160 rows.
My problem is when attempting to display over time data, there is no functioning "year" column or any data Power BI recognises as a date. How do i convert from the year info in the column name to use-able/able to be filtered year information?
you should unpivot and pivot again on the Power Query side. then you can use DATE(<year>, <month>, <day>) on the powerbi side...
try :
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45Wcg1VUNJRMgQRRiDCWClWJ1opNNgRIQIiTJRiYwE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Country = _t, #"2020 Rank X" = _t, #"2020 Rank Y" = _t, #"2021 Rank X" = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Country", type text}, {"2020 Rank X", Int64.Type}, {"2020 Rank Y", Int64.Type}, {"2021 Rank X", Int64.Type}}),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Country"}, "Attribute", "Value"),
#"Added Custom" = Table.AddColumn(#"Unpivoted Other Columns", "Year", each Text.Start([Attribute],4)),
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Year", type date}}),
#"Pivoted Column" = Table.Pivot(#"Changed Type1", List.Distinct(#"Changed Type1"[Attribute]), "Attribute", "Value")
in
#"Pivoted Column"
I am building a Power Bi Q&A Dashboard that shows pass or fail within specific criteria. 1 meaning Pass, 0 meaning Fail. If any of the Categories Fail, the entire row fails.
Example:
Rep Name
Categories 1
Categories 2
Categories 3
Pass/Fail
Bob Smith
1
1
1
1
Tyler Jones
1
0
0
0
What I am looking for is a way to say, If (Pass/Fail) = 0 then list all columns have a value = 0.
In this example, I should get a result of Tyler Jones Failed in Criteria 2 & 3
What is the best way in either Dax or Mcode to do this?
You can unpivot your Category and use a CONCATENAX. Below example.
M transformation:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WcspPUgjOzSzJUNJRMkTBsTrRSiGVOalFCl75eanFUHEDOI6NBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Rep Name" = _t, #"Categories 1" = _t, #"Categories 2" = _t, #"Categories 3" = _t, #"Pass/Fail" = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Rep Name", type text}, {"Categories 1", Int64.Type}, {"Categories 2", Int64.Type}, {"Categories 3", Int64.Type}, {"Pass/Fail", Int64.Type}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {"Rep Name", "Pass/Fail"}, "Attribute", "Value"),
#"Removed Columns" = Table.RemoveColumns(#"Unpivoted Columns",{"Pass/Fail"})
in
#"Removed Columns"
DAX measure:
FailAts = CONCATENATEX(CALCULATETABLE ( VALUES ( 'Table (2)'[Attribute] ),'Table (2)'[Value] = 0 ), 'Table (2)'[Attribute]," ")
My datasouce looks like following:
Case_ID;Date;Status_ID;Amount
1;01.09.2021;0;300
1;05.09.2021;2;320
1;06.09.2021;3;320
2;05.09.2021;3;100
3;02.09.2021;0;200
3;07.09.2021;1;200
...
The logic is that for a particular businness case the Status_ID and the Amount is valid from the "Date" until a new change or until the end of the calendar.
For the above data and end of calendar as of 8.9.2021 my required measure should give following output.
Date Case_ID Status_ID Amount
1.9.2021 1 0 300
2.9.2021 1 0 300
3.9.2021 1 0 300
4.9.2021 1 0 300
5.9.2021 1 2 320
6.9.2021 1 3 320
7.9.2021 1 3 320
8.9.2021 1 3 320
5.9.2021 2 3 100
6.9.2021 2 3 100
7.9.2021 2 3 100
8.9.2021 2 3 100
2.9.2021 3 0 200
3.9.2021 3 0 200
4.9.2021 3 0 200
5.9.2021 3 0 200
6.9.2021 3 0 200
7.9.2021 3 1 200
8.9.2021 3 1 200
How can I construct such a measure with DAX?
I have found several blogs on "Semiadditive measures" with several approaches how to get the last amount for the Case_ID but I do not know how to handle the changing status.
If Power Query Editor create a new table using the below code-
Note: Replace "your_table_name" with your original table name from the whole script.
let
Source = Table.SelectColumns(your_table_name, {"Case_ID", "Date"}),
#"Grouped Rows" = Table.Group(Source, {"Case_ID"}, {{"min_date", each List.Min([Date]), type nullable date}, {"max_date", each List.Max([Date]), type nullable date}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each ([max_date]-[min_date])),
#"Extracted Days" = Table.TransformColumns(#"Added Custom",{{"Custom", Duration.Days, Int64.Type}}),
#"Added Custom1" = Table.AddColumn(#"Extracted Days", "Custom.1", each List.Range({0..[Custom]},0)),
#"Expanded Custom.1" = Table.ExpandListColumn(#"Added Custom1", "Custom.1"),
#"Added Custom2" = Table.AddColumn(#"Expanded Custom.1", "Custom.2", each Date.AddDays([min_date],[Custom.1])),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom2",{"min_date", "max_date", "Custom", "Custom.1"}),
#"Renamed Columns" = Table.RenameColumns(#"Removed Columns",{{"Custom.2", "Date"}}),
#"Changed Type" = Table.TransformColumnTypes(#"Renamed Columns",{{"Date", type date}}),
#"Sorted Rows" = Table.Sort(#"Changed Type",{{"Case_ID", Order.Ascending}, {"Date", Order.Ascending}}),
#"Merged Queries" = Table.NestedJoin(#"Sorted Rows", {"Case_ID", "Date"}, your_table_name, {"Case_ID", "Date"}, "your_table_name", JoinKind.LeftOuter),
#"Expanded your_table_name" = Table.ExpandTableColumn(#"Merged Queries", "your_table_name", {"Status_ID", "Amount"}, {"your_table_name.Status_ID", "your_table_name.Amount"}),
#"Renamed Columns1" = Table.RenameColumns(#"Expanded your_table_name",{{"your_table_name.Status_ID", "Status_ID"}, {"your_table_name.Amount", "Amount"}}),
#"Filled Down" = Table.FillDown(#"Renamed Columns1",{"Status_ID", "Amount"})
in
#"Filled Down"
Here is the output-
Since you were lookong for a simple DAX solution:
Last Amount =
VAR current_date =
MAX('Calendar'[Date])
VAR last_date =
CALCULATE(
MAX('Table'[Date]),
'Calendar'[Date] <= current_date
)
RETURN
CALCULATE(
MAX('Table'[Amount]),
'Calendar'[Date] = last_date
)
In a table visual, ordered by Case_ID, this looks like
I have a number of columns in my table which have text values that fall into categories - e.g. column "ABC" has 9000 rows but every row must have a value in the set {"A","B","C"}. Other columns like Gender have "M"/"F"/null
For each column, I'd like to convert it into an integer list in-place - so A:1, B:2, C:3 etc.
I've been trying out using List.Distinct to extract the values to a temp table, adding an index column to that and using a join to transform the initial column based on that mapping in the temp table. However this seems slow and I'm not sure how to run this over all columns in my table (or at least Table.ColumnsOfType(Source, {type nullable text}) to select the categorical columns...).
Any suggestions?
Before
Gender
Fruit
[...]
F
Cat
F
Dog
M
Lemon
M
Dog
M
Lemon
null
Cat
M
Dog
After
Gender
Fruit
[...]
1
1
1
2
2
3
2
2
2
3
null
1
2
2
In PowerQuery, this seems to work for any number of columns
Replace all nulls with something else, here +=+
Add Index
Unpivot
Remove duplicates
Group, add index to each group
Merge back into original and expand
Repivot
Remove extra columns
Before and After:
Full code:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Replaced Value" = Table.ReplaceValue(Source,null,"+=+",Replacer.ReplaceValue,Table.ColumnNames(Source)),
#"Added Index" = Table.AddIndexColumn(#"Replaced Value", "Index", 0, 1),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Index"}, "Attribute", "Value"),
// derive a table of replacements
#"Removed Duplicates" = Table.Distinct(#"Unpivoted Other Columns", {"Attribute", "Value"}),
#"Grouped Rows" = Table.Group(#"Removed Duplicates", {"Attribute"}, {{"GRP", each Table.AddIndexColumn(_, "Index2", 1, 1), type table}}),
#"Expanded GRP" = Table.ExpandTableColumn(#"Grouped Rows", "GRP", {"Value", "Index2"}, {"Value", "Index2"}),
//replace originals
#"Merged Queries" = Table.NestedJoin(#"Unpivoted Other Columns",{"Attribute", "Value"},#"Expanded GRP",{"Attribute", "Value"},"EG",JoinKind.LeftOuter),
#"Expanded Table1" = Table.ExpandTableColumn(#"Merged Queries", "EG", {"Index2"}, {"Index2"}),
#"Removed Columns" = Table.RemoveColumns(#"Expanded Table1",{"Value"}),
#"Pivoted Column" = Table.Pivot(#"Removed Columns", List.Distinct(#"Removed Columns"[Attribute]), "Attribute", "Index2", List.Sum),
#"Removed Columns1" = Table.RemoveColumns(#"Pivoted Column",{"Index"})
in #"Removed Columns1"
I need some help. My data set looks currently like this:
Date Ticket (1/0) Week number
01.07.2020 0 1
01.07.2020 1 1
01.07.2020 1 1
01.07.2020 0 1
15.07.2020 0 2
15.07.2020 0 2
15.07.2020 0 2
01.08.2020 1 3
01.08.2020 1 3
01.08.2020 0 3
01.08.2020 0 3
01.08.2020 1 3
The end result that I need should be something like this:
Date 01.07.2020 15.07.2020 01.08.2020
Development of tickets 2 -2 1
I need the end matrix to sum the tickets in that week and substract the tickets of the previous week from it. How do I achieve that? How should the measure look like?
Thanks for the help!
Let your table name is - your_table_name
Now create a new table new_table_name using this below code-
let
Source = your_table_name,
#"Replaced Value" = Table.ReplaceValue(#"Source",".","-",Replacer.ReplaceText,{"Date"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Replaced Value",{{"Date", type date}}),
#"Grouped Rows" = Table.Group(#"Changed Type1", {"Date", "Week number"}, {{"sum_tickets", each List.Sum([#"Ticket (1/0)"]), type nullable number}}),
#"Added Custom" = Table.AddColumn(#"Grouped Rows", "Custom", each [Week number] + 1),
#"Merged Queries" = Table.NestedJoin(#"Added Custom", {"Week number"}, #"Added Custom", {"Custom"}, "Added Custom", JoinKind.LeftOuter),
#"Expanded Added Custom" = Table.ExpandTableColumn(#"Merged Queries", "Added Custom", {"sum_tickets"}, {"Added Custom.sum_tickets"}),
#"Sorted Rows" = Table.Sort(#"Expanded Added Custom",{{"Week number", Order.Ascending}}),
#"Added Custom1" = Table.AddColumn(#"Sorted Rows", "Final_Total", each [sum_tickets] - [Added Custom.sum_tickets]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"sum_tickets", "Custom", "Added Custom.sum_tickets"})
in
#"Removed Columns"
This is the table output-
Now add a matrix visual and add Date to Column field and Final_total to the Values field. The output will be as below-