Sorry guys, but you are falling into the standard trap of using unnecessary dynamic code when an array already does what you want without the pain!
If you already have an array of units, then they are numbered by the indices they occupy in the array, so you can access them easily without having to mess around with dynamic code at all (dynamic code is more complex and harder to debug).
Then, when you want to access the soldier, instead of using:
_frog = call compile format ["soldier%1", _i];
You can simply use:
_frog = soldiers select _i;