The $(basename f) command substitution that you use in your command would be evaluated exactly once (yielding the string f), before the xargs command is even started. This is why your code fails to copy the files to the correct names.
The "No such file or directory" error that you get is due to the f in DIR_OUT/copied_f being replaced by the pathnames of the files found by find.
A more robust way of doing the same thing,
find . -type f -name '*.txt' -exec sh -c '
for pathname do
cp "$pathname" "DIR_OUT/copied_${pathname##*/}"
done' sh {} +
Or, with xargs while taking care to pass the found pathnames between find and xargs as nul-terminated strings:
find . -type f -name '*.txt' -print0 |
xargs -0 sh -c '
for pathname do
cp "$pathname" "DIR_OUT/copied_${pathname##*/}"
done' sh
In both of these variations, we call a small in-line shell script that loops over the given pathnames and copies them to new names under the directory DIR_OUT. The ${pathname##*/} may be replaced by $( basename "$pathname" ).
Note that -print0 (in find) and -0 (in xargs) are non-standard, but commonly implemented.
Related:
$(), evaluates it, (resulting inf), start up thefindandxargswith the resulting parameters. Quoting is needed to prevent that... Butxargsis not a shell and does not understand things like$()on its own... – Gert van den Berg Jun 13 '19 at 06:37