Home » Fill Down and Up by Customer

Fill Down and Up by Customer

Fill down / up all 4 columns for different customer IDs. For any Customer, only one of the cells in respective column is populated. That is how you need to identify the first row and last row for a Customer. (I have shaded this in different colors to provide clarity) Type column will be suffixed with 1, 2, 3 after fill down / up for a Customer.

📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 147
Challenge Difficulty: ⭐️⭐️⭐️⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Fill Down and Up by Customer with Power Query

Power Query solution 1 for Fill Down and Up by Customer, proposed by Bo Rydobon 🇹🇭:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  cn = Table.ColumnNames(Source), 
  Ans = Table.Combine(
    Table.Group(
      Table.FromColumns(
        Table.ToColumns(Source)
          & {
            List.Transform(
              List.Accumulate(
                Table.ToRows(Source), 
                {}, 
                (s, l) => s & {List.Last(s, 0) + List.NonNullCount(l)}
              ), 
              each Number.RoundUp(_ / 4)
            )
          }, 
        cn & {"G"}
      ), 
      "G", 
      {
        "T", 
        each Table.SelectColumns(
          Table.ReplaceValue(
            Table.AddIndexColumn(Table.FillUp(Table.FillDown(_, cn), cn), "i", 1), 
            "", 
            each Text.From([i]), 
            (c, o, n) => c & n, 
            {"Type"}
          ), 
          cn
        )
      }
    )[T]
  )
in
  Ans
Power Query solution 2 for Fill Down and Up by Customer, proposed by Zoran Milokanović:
let
  Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content], 
  R = List.Reverse, 
  F = each List.Accumulate(
    _, 
    {}, 
    (s, c) =>
      let
        l = List.Last(s, c), 
        v = each c{_} ?? l{_}
      in
        s & {if List.Count(List.Difference(l, c)) = 4 then c else {v(0), v(1), v(2), v(3)}}
  ), 
  S = Table.FromRows(
    List.Accumulate(
      F(R(F(R(Table.ToRows(Source))))), 
      {}, 
      (s, c) =>
        let
          l = List.Last(s, {0})
        in
          s
            & {
              List.RemoveLastN(c)
                & {
                  c{3}
                    & (
                      if l{0} <> c{0} then
                        "1"
                      else
                        Text.From(Number.From(Text.Select(l{3}, {"0" .. "9"})) + 1)
                    )
                }
            }
    ), 
    Table.ColumnNames(Source)
  )
in
  S
Power Query solution 3 for Fill Down and Up by Customer, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Col = Table.AddColumn(Source, "Custom", each List.Count(List.RemoveNulls(Record.ToList(_)))), 
  Lista = List.Skip(
    List.Accumulate(
      Col[Custom], 
      {0}, 
      (s, c) => s & {if List.Last(s) + c <= 4 then List.Last(s) + c else c}
    )
  ), 
  Gen = List.Generate(
    () => [x = 0, y = 1], 
    each [x] < List.Count(Lista), 
    each [x = [x] + 1, y = if Lista{[x]} < 4 then [y] + 1 else 1], 
    each [y]
  ), 
  Rep = List.Transform(List.Select(List.Zip({Lista, Gen}), each _{0} = 4), each _{1}), 
  List2 = List.Combine(
    List.Transform(
      List.Zip(
        {
          Table.ToRows(
            Table.FromColumns(List.Transform(Table.ToColumns(Source), each List.RemoveNulls(_)))
          ), 
          Rep
        }
      ), 
      each List.Repeat({_{0}}, _{1})
    )
  ), 
  Sol = Table.FromRows(
    List.Transform(
      {0 .. List.Count(List2) - 1}, 
      each List.RemoveLastN(List2{_}) & {List.Last(List2{_}) & Text.From(Gen{_})}
    ), 
    Table.ColumnNames(Source)
  )
in
  Sol
Power Query solution 4 for Fill Down and Up by Customer, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  Gen = List.Skip(
    List.Generate(
      () => [x = 0, z = 0, y = {}], 
      each [z] <= Table.RowCount(Source), 
      each [
        x = if List.Count([y]) < 4 then [x] + 1 else 1, 
        z = [z] + 1, 
        y = 
          if List.Count([y]) < 4 then
            List.RemoveNulls([y] & Table.ToRows(Source){[z]})
          else
            List.RemoveNulls(Table.ToRows(Source){[z]})
      ], 
      each [[y], [x]]
    )
  ), 
  Sel = List.Transform(
    List.Select(List.Transform(Gen, each Record.ToList(_)), each List.Count(_{0}) = 4), 
    each _{1}
  ), 
  Zip = List.Zip(
    {Table.ToRows(Table.FromColumns(List.Transform(Table.ToColumns(Source), List.RemoveNulls)))}
      & {Sel}
  ), 
  Tabla = Table.FromRows(
    List.Combine(List.Transform(Zip, each List.Repeat({_{0}}, _{1}))), 
    Table.ColumnNames(Source)
  ), 
  Sol = Table.ExpandListColumn(
    Table.Group(
      Tabla, 
      List.RemoveLastN(Table.ColumnNames(Source)), 
      {{"Type", each List.Transform({1 .. List.Count([Type])}, (x) => [Type]{0} & Text.From(x))}}
    ), 
    "Type"
  )
in
  Sol
Power Query solution 5 for Fill Down and Up by Customer, proposed by Luan Rodrigues:
let
  Fonte = Tabela1, 
  pa = Table.FillDown(Fonte, {"Cust ID"}), 
  gp = Table.ToColumns(Fonte)
    & {
      Table.FillDown(
        Table.Combine(
          Table.Group(
            pa, 
            {"Cust ID"}, 
            {
              {
                "Contagem", 
                each Table.RemoveColumns(Table.FillUp(_, Table.ColumnNames(Fonte)), {"Cust ID"})[
                  [Type]
                ]
              }
            }
          )[Contagem]
        ), 
        {"Type"}
      )[Type]
    }, 
  tab = Table.FromColumns(gp, Table.ColumnNames(Fonte) & {"val"}), 
  g = Table.Group(
    tab, 
    {"val"}, 
    {
      {
        "Contagem", 
        each Table.AddIndexColumn(
          Table.FillUp(Table.FillDown(_, Table.ColumnNames(Fonte)), Table.ColumnNames(Fonte)), 
          "Ind", 
          1, 
          1
        )
      }
    }, 
    GroupKind.Local
  )[Contagem], 
  res = Table.Combine(
    List.Transform(
      g, 
      each Table.RemoveColumns(
        Table.AddColumn(_, "Tipo", each [Type] & Text.From([Ind])), 
        {"val", "Type", "Ind"}
      )
    )
  )
in
  res
Power Query solution 6 for Fill Down and Up by Customer, proposed by Bhavya Gupta:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  ToCols = Table.ToColumns(Source), 
  ColNames = Table.ColumnNames(Source), 
  Output = Table.Combine(
    Table.Group(
      Table.FromColumns(
        ToCols
          & {
            List.Transform(
              List.Zip(
                List.Transform(
                  ToCols, 
                  each List.Skip(
                    List.Accumulate(_, {0}, (x, y) => x & {List.Last(x) + Number.From(y <> null)})
                  )
                )
              ), 
              List.Max
            )
          }, 
        ColNames & {"Group"}
      ), 
      {"Group"}, 
      {
        {
          "All", 
          each Table.SelectColumns(
            Table.ReplaceValue(
              Table.AddIndexColumn(Table.FillUp(Table.FillDown(_, ColNames), ColNames), "Index", 1), 
              each [Index], 
              null, 
              (a, b, c) => a & Text.From(b), 
              {"Type"}
            ), 
            ColNames
          )
        }
      }
    )[All]
  )
in
  Output
Power Query solution 7 for Fill Down and Up by Customer, proposed by Ramiro Ayala Chávez:
let
  Origen = Excel.CurrentWorkbook(){[Name = "Tabla1"]}[Content], 
  a = List.Transform(Table.ToColumns(Origen), each List.RemoveNulls(_)), 
  b = Table.ToRows(Table.FromColumns(a)), 
  c = {0 .. List.Count(b) - 1}, 
  d = {3, 4, 3, 5, 1}, 
  e = List.Transform(c, each List.Split(List.Repeat(b{_}, d{_}), 4)), 
  f = List.Transform(
    e, 
    each List.Transform(_, each Table.Transpose(Table.FromList(_, Splitter.SplitByNothing())))
  ), 
  g = List.Transform(f, each Table.Combine(_)), 
  h = Table.Combine(List.Transform(g, each Table.AddIndexColumn(_, "I", 1))), 
  i = List.Zip({Table.ColumnNames(h), Table.ColumnNames(Origen) & {"I"}}), 
  j = Table.TransformColumnTypes(Table.RenameColumns(h, i), {{"I", type text}}), 
  Sol = Table.RenameColumns(
    Table.RemoveColumns(Table.AddColumn(j, "J", each [Type] & [I]), {"Type", "I"}), 
    {{"J", "Type"}}
  )
in
  Sol
Power Query solution 8 for Fill Down and Up by Customer, proposed by Eric Laforce:
leted then add in the Result-List 
 1 innerTable with repeated records + suffix[Type] by added index 
2) Combine InnerTables from previous step
 
let
 Source = Excel.CurrentWorkbook(){[Name="tData147"]}[Content],
 CN = Table.ColumnNames(Source), NC = List.Count(CN), LVNull = List.Repeat({null}, NC),
 Transform = List.Accumulate(Table.ToRows(Source), [r={}, v=LVNull, i=0], (s,c)=>let
 _V = List.Transform(List.Zip({c, s[v]}), each _{0}??_{1}),
 _VC = List.NonNullCount(_V) = NC,
 _NewT = if (_VC=false) then null else let
 _R = Record.FromList(_V, CN),
 _T = Table.FromRecords(List.Repeat({_R}, s[i]+1)),
 _TI = Table.ReplaceValue(Table.AddIndexColumn(_T,"_idx_",1),
 "", each Text.From([_idx_]), (cur,old,new)=> cur&new, {"Type"})
 in Table.RemoveColumns(_TI, "_idx_")
 in if (_VC) then [r=s[r] & {_NewT}, v=LVNull, i=0] else [r=s[r], v=_V, i=s[i]+1] ),
 Result = Table.Combine(Transform[r])
in
 Result


                    
                  
          
Power Query solution 9 for Fill Down and Up by Customer, proposed by Albert Cid Cañigueral:
let
  Origen = Excel.CurrentWorkbook(){[Name = "Tabla1"]}[Content], 
  ndConteo = Table.AddColumn(Origen, "Conteo", each List.Count(List.RemoveNulls(Record.ToList(_)))), 
  ndIndice = Table.AddIndexColumn(ndConteo, "Indice", 1), 
  ndAcumulado = Table.AddColumn(
    ndIndice, 
    "Acumulado", 
    each Number.RoundUp(List.Sum(List.Range(ndIndice[Conteo], 0, [Indice])) / 4)
  ), 
  ndAgrupo = Table.Group(
    ndAcumulado, 
    "Acumulado", 
    {"Grupos", each [[Cust ID], [Cust Name], [Amount], [Type]]}
  ), 
  ndColIndice = Table.AddColumn(
    ndAgrupo, 
    "Tablas", 
    each 
      let
        a = Table.AddIndexColumn([Grupos], "Indice", 1), 
        b = Table.FillDown(a, {"Cust ID", "Cust Name", "Amount", "Type"}), 
        c = Table.FillUp(b, {"Cust ID", "Cust Name", "Amount", "Type"})
      in
        c
  ), 
  ndCombinar = Table.Combine(ndColIndice[Tablas]), 
  ndCombinoCols = Table.CombineColumns(
    Table.TransformColumnTypes(ndCombinar, {{"Indice", type text}}, "es-ES"), 
    {"Type", "Indice"}, 
    Combiner.CombineTextByDelimiter("", QuoteStyle.None), 
    "Type"
  )
in
  ndCombinoCols
Power Query solution 10 for Fill Down and Up by Customer, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
  S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  No = List.Count(Table.ColumnNames(S)), 
  A = Table.AddColumn(S, "N", each List.NonNullCount(Record.ToList(_))), 
  B = Table.AddIndexColumn(A, "I", 1, 1, Int64.Type), 
  C = Table.AddColumn(
    B, 
    "N2", 
    each List.Accumulate(
      List.Range(B[N], 0, [I]), 
      0, 
      (S, C) => if (S + C) < No + 1 then S + C else C
    )
  ), 
  D = Table.AddColumn(C, "G", each if [N2] = 4 then [I] else null), 
  E = Table.FillUp(D, {"G"}), 
  F = Table.Group(E, {"G"}, {{"X", each _}}), 
  G = Table.AddColumn(
    F, 
    "X2", 
    each Table.AddIndexColumn(
      Table.FillUp(Table.FillDown([X], Table.ColumnNames([X])), Table.ColumnNames([X])), 
      "Ind", 
      1, 
      1
    )
  ), 
  H = Table.SelectColumns(G, {"X2"}), 
  I = Table.ExpandTableColumn(
    H, 
    "X2", 
    {"Cust ID", "Cust Name", "Amount", "Type", "Ind"}, 
    {"Cust ID", "Cust Name", "Amount", "Type", "Ind"}
  ), 
  J = Table.CombineColumns(
    Table.TransformColumnTypes(I, {{"Ind", type text}}, "en-US"), 
    {"Type", "Ind"}, 
    Combiner.CombineTextByDelimiter("", QuoteStyle.None), 
    "Type.1"
  )
in
  J
Power Query solution 11 for Fill Down and Up by Customer, proposed by Mihai Radu O:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  tblColumnN = Table.ColumnNames(Source), 
  NrWordsRow = Table.AddColumn(
    Source, 
    "NrWords", 
    each List.NonNullCount(List.Transform(Record.FieldValues(_), Text.From))
  ), 
  index = Table.AddIndexColumn(NrWordsRow, "Index", 1, 1, Int64.Type), 
  Limits = Table.AddColumn(
    index, 
    "L", 
    each 
      let
        rt = List.Sum(List.FirstN(index[NrWords], [Index])), 
        a  = if rt / 4 = Number.IntegerDivide(rt, 4) then rt / 4 else null
      in
        a
  ), 
  #"Filled Up" = Table.FillUp(Limits, {"L"}), 
  #"Grouped Rows" = Table.Combine(
    Table.Group(
      #"Filled Up", 
      {"L"}, 
      {
        {
          "all", 
          each 
            let
              a = Table.FillUp(Table.FillDown(_, tblColumnN), tblColumnN)[
                [Cust ID], 
                [Cust Name], 
                [Amount], 
                [Type]
              ], 
              b = Table.AddIndexColumn(a, "Index", 1), 
              c = Table.CombineColumns(
                Table.TransformColumnTypes(b, {{"Index", type text}}), 
                {"Type", "Index"}, 
                Combiner.CombineTextByDelimiter(""), 
                "Type"
              )
            in
              c
        }
      }
    )[all]
  )
in
  #"Grouped Rows"
Power Query solution 12 for Fill Down and Up by Customer, proposed by Sandeep Marwal:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  #"Added Custom" = Table.AddColumn(
    Source, 
    "Custom", 
    each List.Count(List.RemoveNulls(Record.ToList(_)))
  ), 
  #"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 1, 1, Int64.Type), 
  #"Added Custom1" = Table.AddColumn(
    #"Added Index", 
    "Custom.1", 
    each List.Sum(List.FirstN(#"Added Custom"[Custom], [Index])) / 4
  ), 
  #"Inserted Round Up" = Table.AddColumn(
    #"Added Custom1", 
    "Round Up", 
    each Number.RoundUp([Custom.1]), 
    Int64.Type
  ), 
  #"Grouped Rows" = Table.Group(
    #"Inserted Round Up", 
    {"Round Up"}, 
    {
      {
        "Count", 
        each Table.AddIndexColumn(
          Table.FillUp(Table.FillDown(_, Table.ColumnNames(_)), Table.ColumnNames(_)), 
          "Index1", 
          1
        )
      }
    }
  )[[Count]], 
  #"Expanded Count" = Table.ExpandTableColumn(
    #"Grouped Rows", 
    "Count", 
    {"Cust ID", "Cust Name", "Amount", "Type", "Index1"}, 
    {"Cust ID", "Cust Name", "Amount", "Type", "Index1"}
  ), 
  #"Merged Columns" = Table.CombineColumns(
    Table.TransformColumnTypes(#"Expanded Count", {{"Index1", type text}}, "en-IN"), 
    {"Type", "Index1"}, 
    Combiner.CombineTextByDelimiter("", QuoteStyle.None), 
    "Merged"
  )
in
  #"Merged Columns"
Power Query solution 13 for Fill Down and Up by Customer, proposed by Glyn Willis:
let
 Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
 #"Renamed Columns" = Table.RenameColumns(Source,{{"Cust ID", "ID"}, {"Cust Name", "N"}, {"Amount", "A"}, {"Type", "T"}}),
 Custom1 = Table.FromColumns(List.Transform(Table.ToColumns(#"Renamed Columns"),List.RemoveNulls),Table.ColumnNames(#"Renamed Columns")),
 Custom2 = 
 let 
 b=Table.ToRecords(#"Renamed Columns"),
 c=List.Count(b)
 in
 Table.FromRecords(
 List.Generate(()=>b{0}&[i=0,r=false],each [i]
Power Query solution 14 for Fill Down and Up by Customer, proposed by Glyn Willis:
let t=Table.Max(_,{"T"})[T] in List.Transform({1..Table.RowCount(_)},(x)=>t&Text.From(x)), type list}
 }, 
 GroupKind.Local, (x,y)=> Int64.From(y[r]))[[Cust ID],[Type]],
 #"Merged Queries" = Table.NestedJoin(#"Grouped Rows", {"Cust ID"}, Custom1, {"ID"}, "D", JoinKind.LeftOuter),
 #"Expanded D" = Table.ExpandTableColumn(#"Merged Queries", "D", {"N", "A"}, {"Cust Name", "Amount"})[[Cust ID],[&Cust Name],[Amount],[Type]],
 #"Expanded Type" = Table.ExpandListColumn(#"Expanded D", "Type")
in
 #"Expanded Type"


                    
                  
          
Power Query solution 15 for Fill Down and Up by Customer, proposed by Arden Nguyen, CPA:
let
  Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content], 
  #"Changed Type" = Table.TransformColumnTypes(
    Source, 
    {{"Cust ID", Int64.Type}, {"Cust Name", type text}, {"Amount", Int64.Type}, {"Type", type text}}
  ), 
  fill_up = Table.FillUp(#"Changed Type", {"Cust ID", "Cust Name", "Amount", "Type"}), 
  group = Table.Group(
    fill_up, 
    {"Cust ID", "Cust Name", "Amount", "Type"}, 
    {
      {
        "Rows", 
        each 
          let
            ct = Table.RowCount(_), 
            fill = Table.Repeat(Table.FirstN(_, 1), ct), 
            result = Table.CombineColumns(
              Table.AddIndexColumn(fill, "Idx", 1), 
              {"Type", "Idx"}, 
              each Text.Combine(List.Transform(_, each Text.From(_))), 
              "Type"
            )
          in
            result
      }
    }, 
    GroupKind.Local, 
    (x, y) => Byte.From(List.Intersect({Record.ToList(x), Record.ToList(y)}) = {})
  ), 
  final = Table.Combine(group[Rows])
in
  final

Solving the challenge of Fill Down and Up by Customer with Excel

Excel solution 1 for Fill Down and Up by Customer, proposed by Bo Rydobon 🇹🇭:
=LET(z,A2:D17,n,MAP(TAKE(z,,-1),LAMBDA(a,ROUNDUP(COUNTA(A2:a)/4,))),h,A1:D1,
VSTACK(h,DROP(REDUCE(0,h,LAMBDA(c,i,LET(d,INDEX(TOCOL(XLOOKUP(i,h,z),3),n),
HSTACK(c,IF(i<>"Type",d,d&SCAN(0,n=DROP(VSTACK(0,n),-1),LAMBDA(a,v,a*v+1))))))),,1)))
Excel solution 2 for Fill Down and Up by Customer, proposed by محمد حلمي:
=REDUCE(A1:D1,SEQUENCE(COUNT(A2:A17)),LAMBDA(C,V,VSTACK(C,LET(e,A2:D17,x,COLUMN(e),J,INDEX(DROP(
REDUCE(0,x,LAMBDA(a,d,HSTACK(a,FILTER(ROW(e),
INDEX(e,,d)>0)))),,1),V),m,MIN(J),
z,SEQUENCE(MAX(J)-m+1),b,BYCOL(INDEX(e,z+m-2,x),
LAMBDA(q,@SORT(q,,-1))),IF(z*(x=4),b&z,b)))))
Excel solution 3 for Fill Down and Up by Customer, proposed by Kris Jaganah:
=LET(a,A2:D17,b,TAKE(a,,1),c,WRAPCOLS(TOCOL(IF(a="",1/0,a),3,1),COUNT(b)),d,COUNTA(b),e,SCAN("",MAP(b,LAMBDA(x,BYROW(XLOOKUP(x,TAKE(c,,1),c,""),ARRAYTOTEXT))),LAMBDA(v,w,IF(w="",v,w))),f,TEXTSPLIT(TEXTJOIN("@",,e),", ","@"),g,BYROW(--(TEXT(a,"0")=f),SUM),h,SEQUENCE(ROWS(a)),i,IF(g=0,XLOOKUP(h+1,h,e),e),j,REDUCE(A1:D1,i&h-XMATCH(i,i)+1,LAMBDA(y,z,VSTACK(y,TEXTSPLIT(z,", ")))),IFERROR(--j,j))

Solving the challenge of Fill Down and Up by Customer with Python

Python solution 2 for Fill Down and Up by Customer, proposed by Jan Willem Van Holst:
import pandas as pd
"C:JWLENOVOPYTHONPower_Query_Challenge_147.csv"
df = pd.read_csv(r"C:JWLENOVOPYTHONPower_Query_Challenge_147.csv", sep=";")
df = df.fillna('')
inputList = [df[df.columns[x]].to_list() for x in range(4)]
valuesList = []
for i in inputList:
 valuesList.append([x for x in i if x!=""])
def noRows(seqNoCustomer):
 listOfElement = [elem[seqNoCustomer] for elem in valuesList]
 PosOfElem = [temp[i].index(listOfElement[i]) for i in range(4)]
 result = max(PosOfElem)-min(PosOfElem)+1
 return result
temp = inputList
listOfNumbersOfRows=[]
for i in range(5):
 numberOfRows = noRows(i)
 listOfNumbersOfRows.append(numberOfRows)
 temp = [elem[numberOfRows:] for elem in temp]
 
answer =[]
for i in range(5):
 for j in range(listOfNumbersOfRows[i]):
 answer.append([valuesList[0][i], valuesList[1][i], valuesList[2][i], valuesList[3][i]+str(j+1)])
                    
                  

Solving the challenge of Fill Down and Up by Customer with R

R solution 1 for Fill Down and Up by Customer, proposed by Konrad Gryczan, PhD:
Holy Guacamole :D That was challenging. 
library(tidyverse)
library(readxl)
input = read_excel("Power Query/PQ_Challenge_147.xlsx", range = "A1:D17")
test = read_excel("Power Query/PQ_Challenge_147.xlsx", range = "F1:I17") %>%
 janitor::clean_names()
reshape <- function(input) {
 input %>%
 janitor::clean_names() %>%
 mutate(nr = row_number()) %>%
 mutate(across(c(cust_id, cust_name, amount, type),
 ~ ifelse(is.na(.), NA, cumsum(!is.na(.))),
 .names = "index_{.col}"),
 max_index = pmax(index_cust_id, index_cust_name, index_amount, index_type, na.rm = TRUE)) %>%
 group_by(max_index) %>%
 mutate(across(c(cust_id, cust_name, amount, type),
 ~ max(., na.rm = TRUE)),
 min_row = min(nr, na.rm = TRUE),
 max_row = max(nr, na.rm = TRUE)) %>%
 ungroup() %>%
 filter(!is.na(max_index)) %>%
 select(-starts_with("index_"), -max_index, -nr) %>%
 distinct() %>%
 mutate(row_seq = map2(min_row, max_row, seq)) %>%
 unnest(row_seq) %>%
 select(-min_row, -max_row, -row_seq) %>%
 group_by(cust_id) %>%
 mutate(type = paste0(type, row_number())) %>%
 ungroup()
}
result = reshape(input)
                    
                  

&&

Leave a Reply