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,
%d
stands for integer. The vector argument is recycled if possible but if it isc(1.5, 1)
it will fail whensprintf()
tries to replace%d
with 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 castr
as 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.