This works:
> sprintf('%d', c(1, 1.5))
[1] "1" "1"
and this doesn't:
> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) :
invalid format '%d'; use format %f, %e, %g or %a for numeric objects
Why?
This works:
> sprintf('%d', c(1, 1.5))
[1] "1" "1"
and this doesn't:
> sprintf('%d', c(1.5, 1))
Error in sprintf("%d", c(1.5, 1)) :
invalid format '%d'; use format %f, %e, %g or %a for numeric objects
Why?
This is actually really interesting question. To start,
%dstands for integer. The vector argument is recycled if possible but if it isc(1.5, 1)it will fail whensprintf()tries to replace%dwith 1.5 (which is not integer).I thought it might be related to the fact that in R both integer and double are numeric mode, for example:
Thus both vectors should be stored as double. More info about vector in R language definition and in the documentation for
? numeric:I might have found the lines in the underlying C code which explain what is going on:
This code does the following: If the vector type is
REALSXP(which means numeric) then convert first member of vector todouble r. Then castras integer and then double and if bytes are still same convert whole vector asINTSXP. Importantly, this code only checks the first element of a vector; if that element can be coerced to integer, then the whole vector is coerced, otherwise the code gives an error.To test this hypothesis one could compile R with a custom
sprintf()wheredouble r = REAL(_this)[0];is changed todouble r = REAL(_this)[1];and test whetherc(1.5, 1)works now or not.