String compression algorithm using functional JavaScript
Style notes

Not putting {, } around single line statement blocks is a bad habit. Always delimit statement code blocks.
In compressCharacters newArray should be a constant. In groupCharacters arr should be a constant.
Consistent naming is important. Your naming is all over the place. You call a string, characters (in compressCharacters), string (in compressString), signature, and e in the forEach. A character you call element. You abbreviate an array to arr in one function and call it newArray in another. Most of the names are describing the type and not the abstracted data that they hold.
Don't add useless or redundant code. In compressCharacters you create a variable result that you do nothing with. Not to mention that forEach does not have a return defined. Also result in groupCharacters is never used.
Don't declare variables outside the scope that they are to be used. newSignature is only used inside reduce but declared outside the callback.

Functional programing means that functions should not have side effect (change the state of anything outside the function's scope.) The reduce callback uses the array arr which breaks the no side effects rule. And the forEach pushes to arr which is also outside the forEach callbacks scope (use map or reduce in that case).
Applying the above you would get something like the following code.
const groupRuns = str =&gt; [...str].reduce((groups, char) =&gt; {
        const last = groups.length - 1;
        if (last &lt; 0 || groups[last][0] !== char) { groups.push(char) }
        else { groups[last] += char }
        return groups;
    }, []);

const concatGroups = groups =&gt; groups.reduce((str, g) =&gt; 
        str + (g.length &gt; 2 ? g[0] + g.length : g)
    , &quot;&quot;);

const compressString = str =&gt; concatGroups(groupRuns(str));

const signature = `aabcbbbaaaaaabcccccdddddddbbba`;
compressString(signature);

Note that rather than add numbers to groups of size 2 the group must be 3 or larger.