c r printf coercion

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.