I have a number of columns where I want to replace all negative values with zeros. My thought was to loop over the columns using the Column List Loop Start node and then have the Math Formula within the loop to do

if($column$<0, 0, $column$)

but the flow gets stuck at the Math Formula node, it doesn't change the column name after the first iteration.

You shoud create the formula with a Java Edit Variable (as String Manipulator has no Variable version). And use that variable formula overriding the Math Formula expression.

The KNIME-way solution consists within the loop in renaming the variable (via flow variable) to something fix (e.g. mybelovedvar), manipulate it with whatever Node you like, then rename it back to the original name (via flow variable).

I noted that I need to first split the table so that columns containing other data (e.g. strings) don't get duplicated every iteration. These columns can then be rejoined after the loop based on the row IDs (see image).

in case you have very large data tables, you might find a column appender node quicker to collate the two sets of columns togeter than a join, The column appender node would not need to reevaluate each row