List the top 3 cities where sum of %change from 2020 to 2021 and 2021 to 2022 is the highest. When %change is calculated, result should be rounded to 0 decimals as rankings will be decided on the basis of 0 decimal values. %change = (Next_Year – Previous_Year)/Previous_Year Hence for Austin % change from 2020 to 2021 = (94-77)/77 = 22% from 2021 to 2022 = (75-94)/94 = -20% Sum of %change = 22% – 20% = 2%.
📌 Challenge Details and Links
ExcelBI Excel Challenge Number: 615
Challenge Difficulty: ⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Rank Cities by Percent Change with Power Query
Power Query solution 1 for Rank Cities by Percent Change, proposed by Kris Jaganah:
let
A = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
B = Table.AddColumn(
A,
"Cal",
each [a = Record.ToList(_), b = Number.Round((a{2} / a{1}), 2) + Number.Round((a{3} / a{2}), 2)][
b
]
),
C = Table.AddRankColumn(B, "Rank", {"Cal", 1}, [RankKind = RankKind.Dense]),
D = Table.SelectRows(C[[Rank], [Cities]], each [Rank] < 4)
in
D
Power Query solution 2 for Rank Cities by Percent Change, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
A = Table.AddColumn(
Source,
"A",
each
let
a = _,
b = List.Skip(Record.ToList(a)),
c = List.Sum(
List.Transform(
{1 .. List.Count(b) - 1},
each Number.Round((b{_} - b{_ - 1}) / b{_ - 1}, 2)
)
),
d = Number.From(Number.ToText(c, "0.##"))
in
d
),
Sol = Table.SelectRows(
Table.AddRankColumn(A, "Rank", {{"A", 1}}, [RankKind = RankKind.Dense]),
each [Rank] < 4
)[[Rank], [Cities]]
in
Sol
Power Query solution 3 for Rank Cities by Percent Change, proposed by Abdallah Ally:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Change = (x, y) => Number.Round((y - x) * 100 / x),
AddCol = Table.AddColumn(Source, "Change", each Change([2020], [2021]) + Change([2021], [2022])),
AddRank = Table.AddRankColumn(AddCol, "Rank", {"Change", 1}, [RankKind = RankKind.Dense]),
Result = Table.SelectRows(AddRank, each [Rank] < 4)[[Rank], [Cities]]
in
Result
Power Query solution 4 for Rank Cities by Percent Change, proposed by Seokho MOON:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Change = Table.AddColumn(
Source,
"Change",
each Number.Round([2021] / [2020], 2) + Number.Round([2022] / [2021], 2) - 2
),
Rank = Table.AddRankColumn(Change, "Rank", {"Change", 1}, [RankKind = RankKind.Dense])[
[Rank],
[Cities]
],
Res = Table.SelectRows(Rank, each [Rank] <= 3)
in
Res
Power Query solution 5 for Rank Cities by Percent Change, proposed by CA Raghunath Gundi:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
ch_1 = Table.AddColumn(Source, "ch_1", each Number.Round([2021] / [2020] - 1, 2), Percentage.Type),
ch_2 = Table.AddColumn(ch_1, "ch_2", each Number.Round([2022] / [2021] - 1, 2), Percentage.Type),
#"ch_1&2" = Table.AddColumn(
ch_2,
"sum",
each Number.Round(List.Sum({[ch_1], [ch_2]}), 2),
Percentage.Type
),
Grp = Table.Group(#"ch_1&2", {"sum"}, {{"Cities", each [Cities]}}),
Sort = Table.AddIndexColumn(
Table.FirstN(Table.Sort(Grp, {{"sum", Order.Descending}}), 3),
"Rank",
1,
1
),
Result = Table.ExpandListColumn(Sort, "Cities")[[Rank], [Cities]]
in
Result
Power Query solution 6 for Rank Cities by Percent Change, proposed by Krzysztof Kominiak:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
AddRank = Table.AddColumn(
Source,
"Rank",
each [
a = List.Skip(Record.ToList(_)),
b = List.Positions(a),
c = List.Accumulate(
b,
{},
(s, c) => s & {try Number.Round((a{c + 1} - a{c}) / a{c}, 2) otherwise null}
),
d = Number.Round(List.Sum(c), 2)
][d]
)[[Cities], [Rank]],
Max3 = List.MaxN(List.Distinct(AddRank[Rank]), 3),
FilterRows = Table.SelectRows(AddRank, each List.Contains(Max3, [Rank])),
Result = Table.Sort(
Table.TransformColumns(FilterRows, {"Rank", each List.PositionOf(Max3, _) + 1}),
{{"Rank", Order.Ascending}}
)
in
Result
Power Query solution 7 for Rank Cities by Percent Change, proposed by Alejandra Horvath CPA, CGA:
let
S = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
C = Table.AddColumn(
S,
"A",
each
let
a = Number.Round,
S1 = a(([2021] - [2020]) / [2020], 1),
S2 = a(([2022] - [2021]) / [2021], 1),
P = a(S1 + S2, 1)
in
P
),
R = Table.AddRankColumn(C, "Rank", {{"A", 1}}, [RankKind = RankKind.Dense]),
Sol = Table.SelectRows(R, each [Rank] <= 3)[[Rank], [Cities]]
in
Sol
Solving the challenge of Rank Cities by Percent Change with Excel
Excel solution 1 for Rank Cities by Percent Change, proposed by Bo Rydobon 🇹🇭:
=LET(x,-BYROW(ROUND(C3:D21/B3:C21,2),SUM),r,MATCH(x,SORT(UNIQUE(x))),SORT(FILTER(HSTACK(r,A3:A21),r<4)))
Excel solution 2 for Rank Cities by Percent Change, proposed by 🇰🇷 Taeyong Shin:
=LET(
n,
-MMULT(
ROUND(
C3:D21/B3:C21,
2
),
{1;1}
),
r,
XMATCH(
n,
GROUPBY(
n,
,
)
),
GROUPBY(
HSTACK(
r,
A3:A21
),
,
,
,
0,
,
r<=3
)
)
Excel solution 3 for Rank Cities by Percent Change, proposed by Kris Jaganah:
=LET(a,C3:C21,b,ROUND(a/B3:B21-1,2)+ROUND(D3:D21/a-1,2),c,ROUND(b,2),d,XMATCH(c,SORT(UNIQUE(c),,-1)),VSTACK({"Rank","Cities"},DROP(SORT(FILTER(HSTACK(b,d,A3:A21),d<4),{2,1},{1,-1}),,1)))
Excel solution 4 for Rank Cities by Percent Change, proposed by Julian Poeltl:
=LET(D,BYROW(B3:D21,LAMBDA(A,ROUND(SUM(ROUND(DROP((A-DROP(A,,1))/A,,-1),2)),2))),S,SORT(HSTACK(A3:A21,D),2),X,DROP(S,,1),V,VSTACK(HSTACK("Rank","Cities"),HSTACK(XMATCH(X,UNIQUE(X)),TAKE(S,,1))),TAKE(V,XMATCH(3,TAKE(V,,1),,-1)))
Excel solution 5 for Rank Cities by Percent Change, proposed by Timothée BLIOT:
=LET(A,A3:A21,B,B3:B21,C,C3:C21,D,D3:D21,R,LAMBDA(n,ROUND(n,2)), E,R((C-B)/B),F,R((D-C)/C), G,MAP(E+F,LAMBDA(x,SUM(--(x<=UNIQUE(R(E+F)))))), SORT(FILTER(HSTACK(G,A),G<=3)))
Excel solution 6 for Rank Cities by Percent Change, proposed by Duy Tùng:
=LET(a,BYROW(ROUND(C3:D21/B3:C21,2),SUM),b,MATCH(a,GROUPBY(a,,,,,-1),),GROUPBY(HSTACK(b,A3:A21),,,,0,,b<4))
Excel solution 7 for Rank Cities by Percent Change, proposed by Sunny Baggu:
=LET(
_v,
ROUND(100 * (C3:C21 - B3:B21) / B3:B21,
0) +
ROUND(100 * (D3:D21 - C3:C21) / C3:C21,
0),
_s,
SORT(
_v,
,
-1
),
_t3,
TAKE(
UNIQUE(
_s
),
3
),
_s3,
SEQUENCE(
ROWS(
_t3
)
),
_a,
SORTBY(
HSTACK(
A3:A21,
_v
),
_v,
-1
),
_b,
XLOOKUP(
TAKE(
_a,
,
-1
),
_t3,
_s3
),
DROP(
FILTER(
HSTACK(
TAKE(
_b,
,
1
),
_a
),
1 - ISNA(
_b
)
),
,
-1
)
)
Excel solution 8 for Rank Cities by Percent Change, proposed by Abdallah Ally:
WITH CTE1 AS
(
SELECT
Cities,
ROUND(([2021] - [2020]) * 100/ [2020],
0) +
ROUND(([2022] - [2021]) * 100 /[2021],
0) AS Change
FROM
ExcelChallenge615
),
CTE2 AS
(
SELECT
Cities,
DENSE_RANK() OVER (ORDER BY Change DESC) AS Rank
FROM
CTE1
)
SELECT
Rank,
Cities
FROM
CTE2
WHERE
Rank < 4
Excel solution 9 for Rank Cities by Percent Change, proposed by Anshu Bantra:
=LET(
data_,
A3:D21,
chg_20_21_,
ROUND((INDEX(
data_,
,
3
) - INDEX(
data_,
,
2
)) / INDEX(
data_,
,
2
) * 100,
0),
chg_21_22_,
ROUND((INDEX(
data_,
,
4
) - INDEX(
data_,
,
3
)) / INDEX(
data_,
,
3
) * 100,
0),
chg_sum_,
chg_20_21_ + chg_21_22_,
sorted_indices_,
XMATCH(
chg_sum_,
SORT(
UNIQUE(
chg_sum_
),
,
-1
)
),
sorted_data_,
SORT(
CHOOSECOLS(
HSTACK(
data_,
sorted_indices_
),
5,
1
),
1,
1
),
FILTER(
sorted_data_,
INDEX(
sorted_data_,
,
1
) < 4
)
)
Excel solution 10 for Rank Cities by Percent Change, proposed by Md. Zohurul Islam:
=LET(cty,A3:A21,a,C3:D21,b,B3:C21,hdr,HSTACK("Rank","Cities"),c,ROUND(a/b,2),d,BYROW(c,SUM),unq,UNIQUE(SORT(d,,-1)),e,XMATCH(d,unq),f,SORTBY(HSTACK(e,cty),e,1),g,FILTER(f,DROP(f,,-1)<=3),h,VSTACK(hdr,g),h)
Excel solution 11 for Rank Cities by Percent Change, proposed by Pieter de B.:
=LET(a,
A3:D21,
c,
CHOOSECOLS,
z,
LAMBDA(x,
y,
ROUND((y-x)/x%,
)),
n,
z(
c(
a,
2
),
c(
a,
3
)
)+z(
c(
a,
3
),
c(
a,
4
)
),
r,
MAP(
n,
LAMBDA(
m,
SUM(
N(
UNIQUE(
n
)>m
)
)
)
)+1,
c(
GROUPBY(
c(
a,
1
),
r,
SUM,
,
0,
2,
r<4
),
2,
1
))
Excel solution 12 for Rank Cities by Percent Change, proposed by Hamidi Hamid:
=LET(aa,
A3:A21,
bb,
B3:B21,
cc,
C3:C21,
dd,
D3:D21,
s,
SORT(HSTACK(A3:D21,
ROUND((cc-bb)/bb,
2)+ROUND((dd-cc)/cc,
2)),
5,
-1),
b,
LARGE(
UNIQUE(
TAKE(
s,
,
-1
)
),
SEQUENCE(
3
)
),
g,
XMATCH(
TAKE(
s,
,
-1
),
b,
1,
1
),
t,
HSTACK(
s,
g
),
x,
ROUND((cc-bb)/bb,
2)+ROUND((dd-cc)/cc,
2),
y,
MAP(
LARGE(
UNIQUE(
x
),
SEQUENCE(
3
)
),
LAMBDA(
a,
ARRAYTOTEXT(
FILTER(
A3:A21,
x>=a
)
)
)
),
z,
UNIQUE(
UNIQUE(
TEXTSPLIT(
CONCAT(
y&", "
),
,
", ",
1
),
1
)
),
HSTACK(
VLOOKUP(
z,
t,
6,
0
),
z
))
Excel solution 13 for Rank Cities by Percent Change, proposed by Asheesh Pahwa:
=LET(p,
ROUND(100*(C3:C21-B3:B21)/B3:B21,
0),
_p,
ROUND(100*(D3:D21-C3:C21)/C3:C21,
0),
_s,
p+_p,
t,
TAKE(
SORT(
UNIQUE(
_s
),
,
-1
),
3
),
s,
SEQUENCE(
ROWS(
t
)
),
r,
REDUCE(
F2:G2,
s,
LAMBDA(
x,
y,
VSTACK(
x,
IFNA(
HSTACK(
y,
FILTER(
A3:A21,
_s=INDEX(
t,
y,
)
)
),
y
)
)
)
),
r)
Excel solution 14 for Rank Cities by Percent Change, proposed by Imam Hambali:
=LET(
d, ROUND(((C3:C21-B3:B21)/B3:B21)*100,0) + ROUND(((D3:D21-C3:C21)/C3:C21)*100,0),
t, TAKE(SORT(UNIQUE(d),,-1),3),
tt, SORT(FILTER(HSTACK(A3:A21,d), BYROW(d=TRANSPOSE(t),OR)),2,-1),
VSTACK({"Rank","Cities"}, HSTACK(XMATCH(TAKE(tt,,-1),t),TAKE(tt,,1)))
)
Excel solution 15 for Rank Cities by Percent Change, proposed by Ernesto Vega Castillo:
=LET(
a,
-BYROW(
ROUND(
C3:D21/B3:C21,
2
),
SUM
),
b,
MATCH(
a,
SORT(
UNIQUE(
a
)
)
),
DROP(
GROUPBY(
HSTACK(
b,
A3:A21
),
b,
MAX,
,
0,
1,
b<=3
),
,
-1
)
)
Excel solution 16 for Rank Cities by Percent Change, proposed by Jorge Alvarez:
=LET(re;BYROW(C3:E21;LAMBDA(v;
LET(_v2020;TOMAR(v;1;1);
_v2021;ELEGIRCOLS(TOMAR(v;1;2);2);
_v2022;TOMAR(v;1;-1);
REDONDEAR((_v2021-_v2020)/_v2020;2)+REDONDEAR((_v2022-_v2021)/_v2021;2))));
or;ORDENAR(re;;-1);
ori;APILARV("Ordenar";or);
se;EXCLUIR(SCAN&(0;or<>ori;LAMBDA(a;v;SI(v;a+1;a)));-1);
APILARH(FILTRAR(se;se<=3);FILTRAR(ORDENARPOR(B3:B21;re;-1);se<=3))
)
Solving the challenge of Rank Cities by Percent Change with Python
Python solution 1 for Rank Cities by Percent Change, proposed by Konrad Gryczan, PhD:
import pandas as pd
path = "615 Top 3 Percentage Change Sum.xlsx"
input = pd.read_excel(path, usecols="A:D", skiprows=1, nrows=20).rename(columns=lambda x: x if x == 'Cities' else f"{x}Y")
test = pd.read_excel(path, usecols="F:G", skiprows=1, nrows=6).rename(columns=lambda x: x.split('.')[0])
.sort_values(["Rank", "Cities"]).reset_index(drop=True)
input['ch1'] = round((input['2021Y'] - input['2020Y']) / input['2020Y'], 2)
input['ch2'] = round((input['2022Y'] - input['2021Y']) / input['2021Y'], 2)
input['cum_ch'] = round(input['ch1'] + input['ch2'], 2)
input['Rank'] = input['cum_ch'].rank(method='dense', ascending=False).astype(int)
input = input.sort_values(by=['Rank', "Cities"])
input = input[['Rank','Cities']].reset_index(drop=True)
input = input[input['Rank'] <= 3]
print(all(input == test)) # True
Python solution 2 for Rank Cities by Percent Change, proposed by Abdallah Ally:
import pandas as pd
change = lambda x, y: round((y - x) * 100 / x)
file_path = 'Excel_Challenge_615 - Top 3 Percentage Change Sum.xlsx'
df = pd.read_excel(file_path, usecols='A:D', skiprows=1)
# Perform data manipulation
df['Rank'] = (
df
.apply(lambda x: change(x[2020], x[2021]) + change(x[2021], x[2022]), axis=1)
.rank(method='dense', ascending=False)
.map(int)
)
df = df[['Rank', 'Cities']][df['Rank'] < 4].sort_values(by='Rank', ignore_index=True)
df
Solving the challenge of Rank Cities by Percent Change with Python in Excel
Python in Excel solution 1 for Rank Cities by Percent Change, proposed by Alejandro Campos:
df = xl("A2:D21", headers=True)
df['Rank'] = (((df[2021] - df[2020]) / df[2020] * 100).round(0) +
((df[2022] - df[2021]) / df[2021] * 100).round(0)).
rank(method='dense', ascending=False).astype(int)
df[df['Rank'] <= 3][['Rank', 'Cities']].sort_values(
by=['Rank', 'Cities']).reset_index(drop=True)
Python in Excel solution 2 for Rank Cities by Percent Change, proposed by Anshu Bantra:
df = xl("A2:D21", headers=True)
df['change'] = round( (df[2021]-df[2020])/df[2020]*100, 0 ) +
round( (df[2022]-df[2021])/df[2021]*100, 0 )
df['Rank'] = df['change'].rank(method='dense', ascending=False)
df = df.sort_values(by='Rank', ascending=True)
df[df['Rank']<4][['Rank','Cities']].reset_index(drop=True)
Solving the challenge of Rank Cities by Percent Change with R
R solution 1 for Rank Cities by Percent Change, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)
path = "Excel/615 Top 3 Percentage Change Sum.xlsx"
input = read_excel(path, range = "A2:D21")
test = read_excel(path, range = "F2:G8") %>%
arrange(Rank, Cities)
result = input %>%
mutate(ch1 = round((`2021` - `2020`)/`2020`,2),
ch2 = round((`2022` - `2021`)/`2021`,2),
cum_ch = ch1 + ch2) %>%
mutate(cum_ch = round(cum_ch,2)) %>%
mutate(rank = dense_rank(-cum_ch)) %>%
filter(rank <= 3) %>%
arrange(rank, Cities) %>%
select(Rank = rank, Cities)
all.equal(result, test, check.attributes = FALSE)
#> [1] TRUE
&&
