Use the unpivot pattern, like this:
=let(
unpivot_, lambda(d,f,g,let(r_,lambda(t,o,h,chooserows(t,sequence(h,1,o))),c_,lambda(t,o,w,choosecols(t,sequence(1,w,o))),s_,lambda(r,c,h,w,r_(c_(d,c,w),r,h)),l_,lambda(c,s_(1,c,1,1)),hr,hstack(s_(1,1,1,f),"Label","Q1"),i,sequence(1,(columns(d)-f)/g,f+1,g),n,tocol(æ,2),reduce(hr,sequence(rows(d)-1,1,2),lambda(z,r,let(e,s_(r,1,1,f),s,reduce(n,i,lambda(t,c,let(x,s_(r,c,1,g),if(single(x)="",t,vstack(t,hstack(e,l_(c),x)))))),vstack(z,s)))))),
split_, lambda(label, col, vstack(iferror(bycol(split(col, ", "), lambda(col, vstack(iferror(regexextract(label, "\[(.+)\]")), col)))))),
data, filter(
hstack(
'Form Responses 1'!A1:A,
'Form Responses 1'!E1:E,
split_('Form Responses 1'!B1, 'Form Responses 1'!B2:B),
split_('Form Responses 1'!C1, 'Form Responses 1'!C2:C),
split_('Form Responses 1'!D1, 'Form Responses 1'!D2:D)
),
len('Form Responses 1'!A1:A)
),
unpivot_(data, 2, 1)
)
With form response data like this:
Timestamp |
Q1 [col1] |
Q1 [col2] |
Q1 [col3] |
Name |
8/6/2023 9:34:20 |
b1, b2, b3 |
c1, c2 |
d1, d2 |
Alice |
8/7/2023 11:02:49 |
b1, b4 |
|
d2, d3, d4 |
Bob |
...the results look like this:
Timestamp |
Name |
Label |
Q1 |
8/6/2023 9:34:20 |
Alice |
col1 |
b1 |
8/6/2023 9:34:20 |
Alice |
col1 |
b2 |
8/6/2023 9:34:20 |
Alice |
col1 |
b3 |
8/6/2023 9:34:20 |
Alice |
col2 |
c1 |
8/6/2023 9:34:20 |
Alice |
col2 |
c2 |
8/6/2023 9:34:20 |
Alice |
col3 |
d1 |
8/6/2023 9:34:20 |
Alice |
col3 |
d2 |
8/7/2023 11:02:49 |
Bob |
col1 |
b1 |
8/7/2023 11:02:49 |
Bob |
col1 |
b4 |
8/7/2023 11:02:49 |
Bob |
col3 |
d2 |
8/7/2023 11:02:49 |
Bob |
col3 |
d3 |
8/7/2023 11:02:49 |
Bob |
col3 |
d4 |
See the sample spreadsheet.