c - Sprintf formato inválido ''% d''
coercion (1)
Esto funciona:
> sprintf(''%d'', c(1, 1.5))
[1] "1" "1"
y esto no
> 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
¿Por qué?
Esta es una pregunta realmente interesante. Para empezar, %d
significa entero. El argumento del vector se recicla si es posible, pero si es c(1.5, 1)
fallará cuando sprintf()
intente reemplazar %d
con 1.5 (que no es entero).
Pensé que podría estar relacionado con el hecho de que en R tanto enteros como dobles son modos numéricos, por ejemplo:
storage.mode(c(1.5, 1))
# [1] "double"
storage.mode(c(1, 1.5))
# [1] "double"
mode(c(1,1.5))
# [1] "numeric"
mode(c(1.5,1))
# [1] "numeric"
Por lo tanto, ambos vectores deben ser almacenados como dobles. ¿Más información sobre vector en la definición de lenguaje R y en la documentación de ? numeric
? numeric
La posible confusión es que R ha usado el modo "numérico" para significar "doble o entero"
Podría haber encontrado las líneas en sprintf.c que explican lo que está pasando:
if(TYPEOF(_this) == REALSXP) {
double r = REAL(_this)[0];
if((double)((int) r) == r)
_this = coerceVector(_this, INTSXP);
Este código hace lo siguiente: Si el tipo de vector es REALSXP
(lo que significa numérico), convierta el primer miembro de vector a double r
. Luego convierta r
como entero y luego doble, y si los bytes siguen siendo los mismos, convierta todo el vector como INTSXP
. Es importante destacar que este código solo verifica el primer elemento de un vector; si ese elemento puede ser forzado a un entero, entonces todo el vector es forzado, de lo contrario el código da un error.
Para probar esta hipótesis, se podría compilar R con un sprintf()
donde double r = REAL(_this)[0];
se cambia a double r = REAL(_this)[1];
y prueba si c(1.5, 1)
funciona ahora o no.