How to handle data over time without a date column? - powerbi

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"

Related

Power Query : Split Table Every n Columns

I have many columns of same table
Table A
Monthly Plan
Weekly plan
Actual
Monthly_Plan1
Weekly_plan 2
Actual_3
A
B
C
D
E
F
I want them as :
Monthly Plan
Weekly plan
Actual
A
B
C
D
E
F
I can not create a separate table and append it because there are so many columns and I cant create too many tables.
Here you go.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WclRQ0lFyAhHOIMIFRLiCCDel2FgA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [#"Monthly Plan " = _t, #"Weekly plan " = _t, #"Actual " = _t, #"Monthly_Plan1 " = _t, #"Weekly_plan 2 " = _t, Actual_3 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Monthly Plan ", type text}, {"Weekly plan ", type text}, {"Actual ", type text}, {"Monthly_Plan1 ", type text}, {"Weekly_plan 2 ", type text}, {"Actual_3", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each List.Split( Record.ToList( _), 3)),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom",{"Custom"}),
#"Expanded Custom" = Table.ExpandListColumn(#"Removed Other Columns", "Custom"),
#"Extracted Values" = Table.TransformColumns(#"Expanded Custom", {"Custom", each Text.Combine(List.Transform(_, Text.From), "|"), type text}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Extracted Values", "Custom", Splitter.SplitTextByDelimiter("|", QuoteStyle.Csv), {"Monthly", "Weekly", "Actual"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Monthly", type text}, {"Weekly", type text}, {"Actual", type text}})
in
#"Changed Type1"
Add a custom column
Remove other columns
Expand
Extract values concatenating with a |
Split the column and rename
If you don't care about row order this also works
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
Combo = List.Split(Table.ColumnNames(Source),3),
#"Added Custom" =List.Accumulate(Combo, #table({"Column1"}, {}),(state,current)=> state & Table.Skip(Table.DemoteHeaders(Table.SelectColumns(Source, current)),1))
in #"Added Custom"

calculating seconds from a numbers/text column which represents the time in hours/minute/seconds

In Power Query i have a column which, for example looks like this
9h8m4s
this means 9 hours, 8 minute and 4 second. the challenge now is that i want to convert this value in the column to be the sum up of the hour, minute and second to be only second which actually equals to 32884 seconds.
and ideas about how to convert it in PowerQuery for Power Bi?
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WssywyDUpVoqNBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Column1 = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Column1", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom",
each let
h = Number.FromText(Text.BeforeDelimiter([Column1],"h")),
m = Number.FromText(Text.BetweenDelimiters([Column1],"h","m")),
s = Number.FromText(Text.BetweenDelimiters([Column1],"m","s"))
in (h*60*60)+(m*60)+s)
in
#"Added Custom"
Split the column by the separators "h", "m" and "s" and combine them as a new column by multiplying minutes with 60 and hours with 3600.
let
Source = Table.FromValue("9h8m4s"),
#"Added Custom1" = Table.AddColumn(
Source, "Seconds", each
Number.FromText(Text.BeforeDelimiter([Value],"h")) * 3600
+ Number.FromText(Text.BetweenDelimiters([Value], "h", "m")) * 60
+ Number.FromText(Text.BetweenDelimiters([Value], "m", "s"))
),
#"Changed Type" = Table.TransformColumnTypes(
#"Added Custom1",{{"Seconds", type number}})
in
#"Changed Type"

Is there a solution to get a list of columns that rows are equal to 0?

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]," ")

How to add new column from calculation on two rows in power BI?

I have following table:
I want to add a new column "Total" using query editor(power Query) such that when "GL" is 'Gross Margin' then "Total" should be 'Gross Margin' on "Total India Market" multiplied by 'Total Net Sales' on "Total India Market" i.e 0.11*65687 and if "GL" is not 'Gross Margin' then "Total India Market"+"Export".
Desired output should look like below:
I do not want calculated column it should be in a query editor i.e power query.
You can achieve this using power query
First add an index column then calculate previous row for Total India Market and then add custom column to calculate total as per requirement
let
Source = Excel.Workbook(File.Contents("C:\Users\anumua2\Downloads\im_25_oct_21.xlsx"), null, true),
Data_Sheet = Source{[Item="Data",Kind="Sheet"]}[Data],
#"Promoted Headers" = Table.PromoteHeaders(Data_Sheet, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(#"Promoted Headers",{{"Date", type date}, {"GL", type text}, {"Domestic Product", type number}, {"Total India Market", type number}, {"Export", type number}}),
#"Added Index" = Table.AddIndexColumn(#"Changed Type", "Index", 1, 1, Int64.Type),
#"Prev" = Table.AddColumn(#"Added Index", "Custom", each #"Added Index"{[Index]-2}[#"Total India Market"]),
#"Renamed Columns" = Table.RenameColumns(Prev,{{"Custom", "Prev_Total India Market"}}),
#"Replaced Errors" = Table.ReplaceErrorValues(#"Renamed Columns", {{"Prev_Total India Market", 0}}),
#"Added Custom" = Table.AddColumn(#"Replaced Errors", "Custom", each if[GL] = "Gross Margin" then [Total India Market]*[Prev_Total India Market] else [Total India Market] + [Export]),
#"Renamed Columns1" = Table.RenameColumns(#"Added Custom",{{"Custom", "Total"}})
in
#"Renamed Columns1"
It seems to be that Total Net Sales is always on the row before Gross Margin.
If that is the case, then in order to multiply a value by the value in the same column preceding row, you'll need to either add an Index column, or, my preference because it calculates faster, add a "shifted column" where the value from the previous row is now on the same row.
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("bZA/C4MwEMW/ijhLzWlyf0anTu2idBEHBykFacHY799LAqXELnnc8Xv3HhnHEkwNNVBZlZ33y14M7+2pw8kIR0FKE5VT9UsPr31ei6s6+nldvG6IBVXQIQegbZx1mem8vbwvLvN2f8QQaDCKiSEAeUh/68JhxxQ4JomX9eUv2fwrDwYCL2hMiuEMP7YPcMhCS6JqWxaTmQ7tQZLY+EWMGZ/a62EJHECb6oNzjrTQ9AE=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, GL = _t, #"Domestic Product" = _t, #"Total India Market" = _t, Export = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"GL", type text},
{"Domestic Product", type number}, {"Total India Market", type number}, {"Export", type number}}),
//add a column = offset column from Total India Market
//This will calculate faster than using an INDEX column
offsetTotalIndiaMarket =
let
tbl = #"Changed Type",
ShiftedList = {null} & List.RemoveLastN(tbl[Total India Market]),
Custom1 = Table.ToColumns(tbl) & {ShiftedList}
in
Table.FromColumns(Custom1, Table.ColumnNames(tbl) & {"Shifted Tot India Market"}),
//add custom column to execute the described calculation
#"Added Custom" = Table.AddColumn(offsetTotalIndiaMarket, "Total", each
if [GL] = "Gross Margin"
then [Total India Market]*[Shifted Tot India Market]
else [Total India Market]+[Export]),
//Remove shifted column
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"Shifted Tot India Market"})
in
#"Removed Columns"
Results
If it is NOT the case that Total Net Sales is always on the line preceding Gross Margin, then we can use a different algorithm. But also have to know if Gross Margin will always have a preceding Total Net Sales, or if we have to account for an inability to calculate also.
If this is the case, respond with a comment to this answer

Power Query Table Transformation

I am using power query in Excel. I have following table generated from a raw SQL query.
ABC_MONTH
ABC_YEAR
XYZ_MONTH
XYZ_YEAR
10
20
30
40
I would like to transform the above table into the following one in power query or tansformations. Kindly help.
NAME
MONTH
YEAR
ABC
10
20
XYZ
30
40
First unpivot all the columns to get this:
Split the Attribute column by the left-most underscore:
To get this:
Then pivot Attribute.2 and Value:
To get the desired output (after renaming Attribute.1 to NAME):
The M code to try:
let
Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjRQ0lEyAhHGIMLEQCk2FgA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [ABC_MONTH = _t, ABC_YEAR = _t, XYZ_MONTH = _t, XYZ_YEAR = _t]),
#"Changed Type" = Table.TransformColumnTypes(Source,{{"ABC_MONTH", Int64.Type}, {"ABC_YEAR", Int64.Type}, {"XYZ_MONTH", Int64.Type}, {"XYZ_YEAR", Int64.Type}}),
#"Unpivoted Columns" = Table.UnpivotOtherColumns(#"Changed Type", {}, "Attribute", "Value"),
#"Split Column by Delimiter" = Table.SplitColumn(#"Unpivoted Columns", "Attribute", Splitter.SplitTextByEachDelimiter({"_"}, QuoteStyle.Csv, false), {"Attribute.1", "Attribute.2"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Split Column by Delimiter",{{"Attribute.1", type text}, {"Attribute.2", type text}}),
#"Pivoted Column" = Table.Pivot(#"Changed Type1", List.Distinct(#"Changed Type1"[Attribute.2]), "Attribute.2", "Value", List.Sum),
#"Renamed Columns" = Table.RenameColumns(#"Pivoted Column",{{"Attribute.1", "NAME"}})
in
#"Renamed Columns"