Align the data as given in answer expected.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 520
Challenge Difficulty: ⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Align Rowwise Data with Power Query
Power Query solution 1 for Align Rowwise Data, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
S = Table.FromColumns(
List.Zip(
List.TransformMany(
Table.ToRows(Source),
each
let
r = List.RemoveLastN(_, each _ = null)
in
List.Combine(
List.Transform(
List.Split(
List.Skip(List.Zip({List.FirstN(Table.ColumnNames(Source), List.Count(r)), r})),
4
),
List.Zip
)
),
(i, _) => {i{0}} & _
)
)
)
in
S
Power Query solution 2 for Align Rowwise Data, proposed by Kris Jaganah:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Calc = Table.AddColumn(
Source,
"Custom",
each
let
a = List.Skip(Record.FieldNames(_)),
b = List.Skip(Record.FieldValues(_)),
c = (Table.ColumnCount(Source) - 1) / 2,
d = List.FirstN(a, c),
e = List.FirstN(b, c),
f = List.LastN(a, c),
g = List.LastN(b, c),
h = Table.FromRows({d, e}) & Table.FromRows({f, g})
in
h
),
Keep = Table.SelectColumns(Calc, {"Group", "Custom"}),
Xpand = Table.ExpandTableColumn(Keep, "Custom", {"Column1", "Column2", "Column3", "Column4"}),
Rmov =
if List.NonNullCount(Record.FieldValues(Xpand{Table.RowCount(Xpand) - 1})) <= 1 then
Table.RemoveRows(Xpand, Table.RowCount(Xpand) - 2, 2)
else
Xpand
in
Rmov
Power Query solution 3 for Align Rowwise Data, proposed by Aditya Kumar Darak 🇮🇳:
let
Source = Excel.CurrentWorkbook(){[Name = "data"]}[Content],
Split = Table.Split(Source, 1),
Transform = List.TransformMany(
Split,
(x) =>
[
D = Table.DemoteHeaders(x),
Tp = Table.Transpose(D),
Sk = Table.Skip(Tp),
R = Table.Split(Sk, 4)
][R],
(x, y) =>
[
H = Table.FromRows({List.Repeat({x[Group]{0}}, 2)}),
S = Table.RemoveLastN(y, each [Column2] = null),
C = if Table.IsEmpty(S) then S else H & S,
R = Table.Transpose(C)
][R]
),
Return = Table.Combine(Transform)
in
Return
Power Query solution 4 for Align Rowwise Data, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Group = Table.Group(
Source,
{"Group"},
{
{
"A",
each
let
a = Table.RemoveColumns(_, "Group"),
b = Table.DemoteHeaders(a),
c = Table.ToColumns(b),
d = List.RemoveLastN(c, each _{1} = null),
e = List.Split(d, 4),
f = List.Transform(e, each Table.FromColumns(_)),
g = Table.Combine(f)
in
g
}
}
),
Sol = Table.ExpandTableColumn(
Group,
"A",
List.Distinct(List.Combine(List.Transform(Group[A], each Table.ColumnNames(_))))
)
in
Sol
Power Query solution 5 for Align Rowwise Data, proposed by Abdallah Ally:
let
Source = Excel.CurrentWorkbook(){[Name = "Table3"]}[Content],
Headers = List.Skip(Table.ColumnNames(Source)),
Headers1 = List.FirstN(Headers, 4),
Headers2 = List.LastN(Headers, 4),
Records = List.Transform(
Table.ToRows(Source),
each [
f = {_{0}},
a = List.FirstN(_, 5),
b = f & List.LastN(_, 4),
c = if List.NonNullCount(a) > 1 then {f & Headers1, a} else {{}},
d = if List.NonNullCount(b) > 1 then {f & Headers2, b} else {{}},
e = List.Select(c & d, each not List.IsEmpty(_))
][e]
),
Result = Table.FromRows(List.Combine(Records))
in
Result
Solving the challenge of Align Rowwise Data with Excel
Excel solution 1 for Align Rowwise Data, proposed by Bo Rydobon 🇹🇭:
=LET(z,A1:Z4,DROP(REDUCE(,SEQUENCE(ROWS(z)),LAMBDA(a,i,LET(v,INDEX(+z,i,),d,DROP(v,,1),b,IF(d="","",d),c,SEQUENCE(,COLUMNS(b))<=MATCH(9^9,b),w,LAMBDA(x,WRAPROWS(FILTER(x,c),4,"")),
u,VSTACK(w(TAKE(DROP(z,,1),1)),w(b)),r,ROWS(u),s,SEQUENCE(r),IFNA(VSTACK(a,HSTACK(IF(s,@v),SORTBY(u,MOD(s-1,r/2)))),"")))),1))
Excel solution 2 for Align Rowwise Data, proposed by Rick Rothstein:
=LET(
f,
LAMBDA(
g,
LET(
h,
WRAPROWS(
B1:I1,
4
),
b,
SUM(
OFFSET(
g,
0,
5,
4
)
)>0,
v,
0+WRAPROWS(
OFFSET(
g,
0,
1,
1,
4+4*b
)&"",
4
),
HSTACK(
SEQUENCE(
2+2*b,
,
g,
0
),
IFERROR(
WRAPROWS(
TOROW(
HSTACK(
h,
v
)
),
4
),
""
)
)
)
),
d,
DROP(
REDUCE(
"",
A2:A4,
LAMBDA(
a,
x,
VSTACK(
a,
f(
x
)
)
)
),
1
),
FILTER(
d,
ISNUMBER(
TAKE(
d,
,
1
)
)
)
)
Excel solution 3 for Align Rowwise Data, proposed by John V.:
=LET(b,REDUCE(0,I2:I4,LAMBDA(a,v,LET(f,LAMBDA(t,r,IF(SUM(r),IFNA(HSTACK(@+A4:v,IF({1,2,3,4}>IFNA(MATCH(1,0/r),),"",VSTACK(t,IF(r="","",r)))),@+A4:v),0)),VSTACK(a,f(B1:E1,TAKE(B4:v,1,4)),f(F1:I1,TAKE(F4:v,1)))))),FILTER(b,TAKE(b,,1)))
Excel solution 4 for Align Rowwise Data, proposed by محمد حلمي:
=LET(
i,
DROP(
REDUCE(
0,
B2:B4,
LAMBDA(
a,
v,
LET(
b,
A4,
s,
@+v:A4,
u,
OFFSET(
v,
,
,
,
4
),
k,
OFFSET(
v,
,
4,
,
4
),
r,
B1:E1,
e,
F1:I1,
VSTACK(
a,
IFNA(
HSTACK(
s,
VSTACK(
IF(
s=b,
IF(
u,
r,
""
),
r
),
u,
IF(
s=b,
IF(
k,
e,
""
),
e
),
k
)
),
s
)
)
)
)
),
1
),
e,
IF(
OR(
TAKE(
i,
-1,
-4
)
),
i,
DROP(
i,
-2
)
),
IF(
e=0,
"",
e
)
)
Excel solution 5 for Align Rowwise Data, proposed by محمد حلمي:
=LET(d,DROP(REDUCE("",A2:A4,LAMBDA(a,g,VSTACK(a,LET(h,WRAPROWS(B1:I1,4),b,SUM(OFFSET(g,0,5,4))>0,
v,0+WRAPROWS(OFFSET(g,0,1,1,4+4*b)&"",4),
HSTACK(SEQUENCE(2+2*b,,g,0),IFERROR(
WRAPROWS(TOROW(HSTACK(h,v)),4),"")))))),1),
FILTER(d,ISNUMBER(TAKE(d,,1))))
Excel solution 6 for Align Rowwise Data, proposed by محمد حلمي:
=LET(i,DROP(REDUCE(0,B2:B4,LAMBDA(a,v,LET(
b,B4,s,@+v:A4,u,OFFSET(v,,,,4),k,OFFSET(v,,4,,4),
r,B1:E1,e,F1:I1,VSTACK(a,IFNA(HSTACK(s,
VSTACK(IF(v=b,IF(u,r,""),r),u,IF(v=b,IF(k,e,""),e),k)),s))))),1),
IF(OR(TAKE(i,-1,-4)),i,DROP(i,-2)))
Excel solution 7 for Align Rowwise Data, proposed by Kris Jaganah:
=LET(
a,
A2:A4,
b,
B1:I1,
c,
B2:I4,
d,
ROWS(
c
),
e,
COLUMNS(
c
),
f,
e/2,
g,
DROP(
TOCOL(
IF(
SCAN(
0,
c,
LAMBDA(
x,
y,
IF(
y="",
1+x,
)
)
)<2,
IF(
c="",
"",
c
),
z
),
3
),
-1
),
h,
TAKE(
TOCOL(
INDEX(
b,
,
SEQUENCE(
e,
d,
,
1/d
)
),
,
1
),
ROWS(
g
)
),
i,
VSTACK(
WRAPROWS(
h,
f,
""
),
WRAPROWS(
g,
f,
""
)
),
j,
ROWS(
i
),
k,
TOCOL(
WRAPCOLS(
SEQUENCE(
j
),
j/2
)
),
HSTACK(
ROUNDUP(
SORT(
k
)/f,
0
),
DROP(
REDUCE(
"",
k,
LAMBDA(
x,
y,
VSTACK(
x,
CHOOSEROWS(
i,
y
)
)
)
),
1
)
)
)
Excel solution 8 for Align Rowwise Data, proposed by Julian Poeltl:
=LET(T,DROP(REDUCE(1,A2:A4,LAMBDA(A,B,VSTACK(A,HSTACK(B,LET(S,SEQUENCE(2,4),F,HSTACK(INDEX(B1:I1,1,S),INDEX(CHOOSEROWS(B2:I4,B),1,S)),C,IF(SUM(CHOOSEROWS(F,2))=0,DROP(F,-1),F),W,WRAPROWS(TOCOL(C),4),D,IF(ROWS(W)>2,W,DROP(W,,-(COLUMNS(TAKE(W,1))-XMATCH(1,IFNA((DROP(W,1)=0)*(DROP(DROP(W,1),,1)=0),0))+1))),D))))),1),C,IFNA(IF(T=0,"",T),""),HSTACK(SCAN(,TAKE(C,,1),LAMBDA(A,B,IF(B="",A,B))),DROP(C,,1)))
Excel solution 9 for Align Rowwise Data, proposed by Julian Poeltl:
=LET(A,DROP(REDUCE(0,A2:A4,LAMBDA(A,B,VSTACK(A,LET(S,SEQUENCE(2,4),F,HSTACK(INDEX(B1:I1,1,S),INDEX(CHOOSEROWS(B2:I4,B),1,S)),C,IF(SUM(CHOOSEROWS(F,2))=0,DROP(F,-1),F),HSTACK(B,WRAPROWS(TOROW(C),4)))))),1),H,HSTACK(SCAN(,TAKE(A,,1),LAMBDA(A,B,IFERROR(B,A))),DROP(A,,1)),IF(H=0,"",H))
Excel solution 10 for Align Rowwise Data, proposed by Timothée BLIOT:
=LET(V,VSTACK,H,HSTACK,A,B1:I1,B,B2:I4,F,LAMBDA(l,m,n,TAKE(INDEX(l,m,),,n)),DROP(DROP(REDUCE(0,ROW(1:3),LAMBDA(y,x,V(y,H(x,V(F(A,1,4))),H(x,F(B,x,4)),H(x,F(A,1,-4)),H(x,F(B,x,-4)))) ),1),-2))
Excel solution 11 for Align Rowwise Data, proposed by Sunny Baggu:
=LET(
_r,
IF(
B2:I4 = "",
"",
B2:I4
),
_a,
TOCOL(
B2:I4
),
_b,
MAX(
SEQUENCE(
ROWS(
_a
)
) * N(
_a <> 0
)
),
_c,
TAKE(
TOCOL(
_r
),
_b
),
_d,
TAKE(
TOCOL(
IF(
A2:A4,
B1:I1
)
),
_b
),
_e,
WRAPROWS(
TOCOL(
HSTACK(
WRAPROWS(
_d,
4,
""
),
WRAPROWS(
_c,
4,
""
)
)
),
4
),
_f,
TOCOL(
TAKE(
WRAPROWS(
TAKE(
TOCOL(
IF(
B1:I1 <> "",
A2:A4
)
),
_b
),
4
),
,
2
)
),
HSTACK(
_f,
_e
)
)
Excel solution 12 for Align Rowwise Data, proposed by Abdallah Ally:
=LET(a,B1:E1,b,F1:I1,v,""&REDUCE("",A2:A4,LAMBDA(x,y,LET(c, OFFSET(y,,1,,4),d,OFFSET(y,,5,,4),VSTACK(x,IF(COUNT(c)>0,VSTACK(HSTACK(y,a),HSTACK(y,c))),IF(COUNT(d)>0,VSTACK(HSTACK(y,b),HSTACK(y,d))))))),FILTER(v,BYROW(v,LAMBDA(x,NOT(OR(ISNA(x)))))))
Excel solution 13 for Align Rowwise Data, proposed by Hamidi Hamid:
=LET(w,A2:A4,bd,B2:I4,r,TOCOL(IFNA(w,B1:I1)),er,r-MAX(r)+TOCOL(bd)+SEQUENCE(COUNTA(r),,0,0),x,FILTER(TOCOL(bd),er<>0),y,FILTER(TOCOL(IFNA(B1:I1,w)),er<>0),n,FILTER(TOCOL(IFNA(w,B1:I1)),er<>0),c,WRAPROWS(x,4,""),v,WRAPROWS(y,4,""),lv,SEQUENCE(ROWS(v)),llv,VSTACK(lv,lv),aq,HSTACK(llv,VSTACK(v,c)),sg,SORT(TOCOL(IF(SEQUENCE(4),TRANSPOSE(w),""))),sq,DROP(SORTBY(aq,TAKE(aq,,1)),,1),dt,HSTACK(sg,IF(sq=0,"",sq)),tu,BYROW(ISERROR(dt)*1,LAMBDA(a,SUM(a))),qq,FILTER(dt,tu=0),qq)
Excel solution 14 for Align Rowwise Data, proposed by And&y Heybruch:
=DROP(
TEXTSPLIT(
TEXTJOIN(
";",
,
BYROW(
A2:I4,
LAMBDA(
a,
HSTACK(
TEXTJOIN(
"|",
FALSE,
TAKE(
a,
,
1
),
INDEX(
B1:I1,
,
SEQUENCE(
,
4,
1
)
)
)
)
&";"&
HSTACK(
TEXTJOIN(
"|",
FALSE,
TAKE(
a,
,
1
),
INDEX(
a,
,
SEQUENCE(
,
4,
2
)
)
)
)
&";"&
HSTACK(
TEXTJOIN(
"|",
FALSE,
TAKE(
a,
,
1
),
INDEX(
B1:I1,
,
SEQUENCE(
,
4,
5
)
)
)
)
&";"&
HSTACK(
TEXTJOIN(
"|",
FALSE,
TAKE(
a,
,
1
),
INDEX(
a,
,
SEQUENCE(
,
4,
6
)
)
)
)
)
)
),
"|",
";"
),
-2
)
Excel solution 15 for Align Rowwise Data, proposed by Eddy Wijaya:
=LET(
raw,B2:I4,
group,A2:A4,
h_1,BYROW(raw,LAMBDA(r,TEXTJOIN(",",FALSE,r))),
h_2,DROP(REDUCE(0, group & "," & h_1, LAMBDA(a,v,
LET(
data, TEXTSPLIT(TEXTAFTER(v, ","), , ","),
lastRow, LOOKUP(2, 1/(data<>""), SEQUENCE(ROWS(data))),
seq, "Value_" & SEQUENCE(lastRow),
adjData, IF(lastRow<5, DROP(data, -4), data),
mergeDS, HSTACK(seq, adjData),
wrapL, LAMBDA(d, TOCOL(d, , TRUE)),
wrapped, IF(lastRow<5, wrapL(mergeDS), VSTACK(wrapL(TAKE(mergeDS, 4)), wrapL(DROP(mergeDS, 4)))),
result, HSTACK(TEXTBEFORE(v, ","), IFNA(WRAPROWS(wrapped, 4), "")),
VSTACK(a, IFNA(result, TEXTBEFORE(v, ",")))
))), 1),IFERROR(--h_2,h_2))
Excel solution 16 for Align Rowwise Data, proposed by Edwin Tisnado:
=LET(
s,
SEQUENCE(
2,
4
),
a,
DROP(
REDUCE(
0,
A2:A4,
LAMBDA(
x,
y,
VSTACK(
x,
HSTACK(
{1;1;1;1}*y,
SORTBY(
VSTACK(
INDEX(
B1:I1,
s
),
INDEX(
INDEX(
B2:I4,
y,
),
s
)
),
{1;2;1;2}
)
)
)
)
),
1
),
DROP(
IF(
a=0,
"",
a
),
-2
)
)
Excel solution 17 for Align Rowwise Data, proposed by El Badlis Mohd Marzudin:
=LET(t,DROP(DROP(REDUCE("",A2:A4,LAMBDA(x,y,VSTACK(x,LET(k,VSTACK($B$1:$E$1,FILTER(B2:E4,A2:A4=y),F1:I1,FILTER(F2:I4,A2:A4=y)),HSTACK(EXPAND(y,ROWS(k),,y),k))))),1),-2),IFNA(HSTACK(TAKE(t,,3),DROP(TAKE(t,,-2),-2)),""))
Solving the challenge of Align Rowwise Data with Python
Python solution 1 for Align Rowwise Data, proposed by Konrad Gryczan, PhD:
import pandas as pd
import numpy as np
path = "520 Alignment of Data.xlsx"
input = pd.read_excel(path, usecols="A:I", nrows= 3, dtype = str)
test = pd.read_excel(path, usecols="A:E", skiprows = 7, header = None, dtype = str)
def correct_transform_dataframe(df):
result = pd.DataFrame()
for _, row in df.iterrows():
group = row['Group']
first_header = pd.DataFrame([[group, 'Value_1', 'Value_2', 'Value_3', 'Value_4']], columns=[0, 1, 2, 3, 4])
first_half = pd.DataFrame([[group] + list(row[['Value_1', 'Value_2', 'Value_3', 'Value_4']])], columns=[0, 1, 2, 3, 4])
second_header = pd.DataFrame([[group, 'Value_5', 'Value_6', 'Value_7', 'Value_8']], columns=[0, 1, 2, 3, 4])
second_half = pd.DataFrame([[group] + list(row[['Value_5', 'Value_6', 'Value_7', 'Value_8']])], columns=[0, 1, 2, 3, 4])
result = pd.concat([result, first_header, first_half, second_header, second_half], ignore_index=True)
return result
result = correct_transform_dataframe(input)
result = result[:-2]
result.loc[8, 3:4] = np.nan
print(result.equals(test)) # True
Solving the challenge of Align Rowwise Data with Python in Excel
Python in Excel solution 1 for Align Rowwise Data, proposed by Abdallah Ally:
df = xl("A1:I4", headers=True)
# Perform data munging
cols = df.columns.tolist()
half_cols = len(cols) // 2
headers1 = cols[1: half_cols + 1]
headers2 = cols[half_cols + 1: ]
values = []
for i in df.index:
f = [i + 1]
a = df.iloc[i, 1: half_cols + 1].tolist()
b = df.iloc[i, half_cols + 1:].tolist()
if len([x for x in a if pd.notna(x)]) > 1:
values.extend([f + headers1, f + a])
if len([x for x in b if pd.notna(x)]) > 1:
values.extend([f + headers2, f + b])
df = pd.DataFrame(values).fillna('')
df
Solving the challenge of Align Rowwise Data with R
R solution 1 for Align Rowwise Data, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "Excel/520 Alignment of Data.xlsx"
input = read_excel(path, range = "A1:I4")
test = read_excel(path, range = "A8:E17", col_names = FALSE) %>% janitor::clean_names()
result = input %>%
pivot_longer(-c(1), names_to = "value_no", values_to = "value") %>%
mutate(v_no = as.numeric(str_extract(value_no, "\d+")),
mod = (v_no - 1) %/% 4) %>%
select(-v_no) %>%
nest_by(Group, mod) %>%
filter(!all(is.na(data$value))) %>%
mutate(data = list(list(t(data)) %>% as.data.frame())) %>%
unnest(data) %>%
ungroup() %>%
select(-mod) %>%
mutate(X4 = ifelse(row_number() == 9, NA, X4),
X3 = ifelse(row_number() == 9, NA, X3))
colnames(result) = colnames(test)
identical(result, test)
# [1] TRUE
&&
