Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
donpep0
Frequent Visitor

Repeat steps multiple times over the same table

Hi all!

 

I'm a little stuck whit power Query, I'm trying to repeat multiple steps over the same table.

My input(Source) looks like this:

DateIndexVolume

9/01

1

1100
9/0221195
9/033139
9/0441013
9/055680
9/066663

9/07

7

 
9/088 
9/099 

 

I want to fill the empty rows with the average of the last 4 periods.

So the volume for index 7 will be the volume average of the Index3,4,5,6,

and the volume for index 8 will be the volume average of Index 4,5,6,7, and so on until the last index.

 

To calculate the volume for index 7, I'm applying the below steps:

col_avg = Table.AddColumn(Source, "avg", each if [Index] = last_index+1 then List.Average(List.Select(List.Range(Source[volume], _[Index]-5,4), each _<>null)) else null, type number)
The last_index is the last index with volume data, in this case, will be 6. I calculated it previously and I stored it in a variable named last_index.

Now, my table looks like this:

DateIndexVolumeavg

9/01

1

1100null
9/0221195null
9/033139null
9/0441013null
9/055680null
9/066663null

9/07

7

 623.75
9/088 null
9/099 null

 

And now I'm creating a new column to merge the volume column with the avg column

 

col_avg_1 = Table.AddColumn(col_avg, "volume", each if [avg] = null then [Volume] else [avg]

 

then I remove the avg column and the Volume column:

#"Removed Columns" = Table.RemoveColumns(col_avg1, {"Volume", "avg"}

 

And now I have this output

DateIndexvolume

9/01

1

1100
9/0221195
9/033139
9/0441013
9/055680
9/066663

9/07

7

623.75
9/088 
9/099 

 

I have to apply the above steps to calculate the next periods over the same table.

 

Do you know how can I create a loop to repeat the above steps n times?

 

Thanks

3 REPLIES 3
KT_Bsmart2gethe
Impactful Individual
Impactful Individual

Hi @donpep0 ,

 

An alternate approach to the situation. I am using Replace.Value instead of List.Accumulate.

Also, I don't use the index column.

 

Starting Point:

KT_Bsmart2gethe_0-1664665417563.png

 

Code:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("NczBDQAhCETRVjacTRRRlFqM/bexgJnDvzwmnENcrfZOhTji1uiWQx2aF7aZKlAJFUscwBHYWFIndHq631cFaqRvuYDLS9mQ7X1JBrJH9wc=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Index = _t, Volume = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Index", Int64.Type}, {"Volume", Int64.Type}}),
    
    //Replace null with average of previous four periods
    #"Replaced Value" = Table.ReplaceValue(
                            #"Changed Type", 
                            each null, 
                            each 
                                let 
                                    LastFourPeriods = Table.SelectRows(
                                                            #"Changed Type", 
                                                            (x)=> x[Date] < [Date] and x[Date] >= Date.AddDays([Date], -4)
                                                        )[Volume], 
                                    FourPeriodAverage = List.Average(
                                                            List.RemoveNulls(LastFourPeriods)
                                                        ) 
                                in 
                                    FourPeriodAverage, 
                            Replacer.ReplaceValue,
                            {"Volume"}
                        )
in
    #"Replaced Value"

 

Outcome:

KT_Bsmart2gethe_1-1664665700821.png

 

 

Regards

KT

wdx223_Daniel
Super User
Super User

= #table(Table.ColumnNames(PreviousStepName),List.Accumulate(Table.ToRows(PreviousStepName),{{},{}},(x,y)=>{x{0}&{{y{0},y{1},y{2}??List.Average(List.LastN(x{1},4))}},x{1}&{y{2}}}){0})

jbwtp
Memorable Member
Memorable Member

Hi @donpep0,

 

You can try something like this:

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WstT1SsxT0lEyBGFDAwOlWB2QoFtqElDACCxoaQoV9E0sAgoYgwSNLaFijgUgMROQmIGhMVxhJVDAFIjNLGAmepWCrDEDYTNjuFgOkG8OxDDTStOBHAuEQHBqAZBjCRaIBQA=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Date = _t, Index = _t, Volume = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Date", type date}, {"Index", Int64.Type}, {"Volume", Int64.Type}}),
    Calculate = List.Accumulate(Table.ToRecords(#"Changed Type"), {[lst = {}]}, (a, n)=> 
        let 
        last = List.Last(a)[lst],
        updateVolume = if n[Volume] = null then Record.TransformFields(n, {"Volume", each List.Average(last)}) else n,
        updateLst = if List.Count(last) = 4 then List.Skip(last) else last,
        addLst = Record.AddField(updateVolume, "lst", updateLst & {updateVolume[Volume]})
        in a & {addLst}),
    Output = Table.FromRecords(List.Skip(Calculate), Value.Type(#"Changed Type"))
in
    Output

 

Kind regards,

John

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors
Top Kudoed Authors