Here another alternative using the REDUCE/VSTACK pattern (1):
=LET(in,A1:C7,C,TAKE(in,,-1),lk,"a",f,FILTER(DROP(in,,-1),C=lk),fa,TAKE(f,,1),
DROP(REDUCE("", UNIQUE(fa), LAMBDA(ac,u, LET(ff, FILTER(f, fa=u),
ffx,DROP(ff,1), first,INDEX(ff,1,),
out, IF(ISERR(ffx),first,VSTACK(first,
HSTACK(IF(TAKE(ffx,,1)=u,""""),TAKE(ffx,,-1)))),
VSTACK(ac, IF(ROWS(ac)=1, out, VSTACK({"",""},out)))))),1))
Here is the output for a and b: changing the lk value for the case of b:

To return an empty string instead of zero in Dog row for the case of b, check my answer to the following question: How can I return blank cells as it is instead of printing as Zeros while using filter function.
The formula only depends on two input range values in and lk, so it is easy to maintain and use in other sheets. The name f filters the first two columns of the input in where the lookup value (lk) match the third column of the input (C). Then we use the REDUCE/VSTACK pattern (1) to iterate over unique values of the first column of the filtered values (fa). The name ff filters the name f where the first column is equal to the unique value u on each iteration.
From there it uses LET to define additional names: first, the first row of ff and ffx the rest of the rows. Keep in mind that it is possible there is only a single row in ff, in such case ffx is equal to #CALC!. We consider this scenario via ISERR call. If ISERR is TRUE it just returns the first row (first), otherwise the first plus the following rows replacing the first column with "" this is how we do it:
HSTACK(IF(TAKE(ffx,,1)=u,""""),TAKE(ffx,,-1)))
It uses the condition TAKE(ffx,,1)=u which is always TRUE on each iteration to generate a constant array with "" values.
Now the name out has the desired output per iteration. The only additional step required is to add an empty row ({"",""}) at the beginning on each iteration, except for the first one. If you add the empty row at the end on each iteration, you don't need this condition, but it will generate an unnecessary empty row in the last iteration, so I prefer to avoid that. The condition to identify the first iteration is ROWS(ac)=1.
(1): how to transform a table in Excel from vertical to horizontal but with different length