sprintf invalid format '%d'

匿名 (未验证) 提交于 2019-12-03 02:56:01

问题:

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?

回答1:

This is actually really interesting question. To start, %d stands for integer. The vector argument is recycled if possible but if it is c(1.5, 1) it will fail when sprintf() 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:

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"

Thus both vectors should be stored as double. More info about vector in R language definition and in the documentation for ? numeric:

The potential confusion is that R has used mode "numeric" to mean ‘double or integer’"

I might have found the lines in the underlying C code which explain what is going on:

if(TYPEOF(_this) == REALSXP) { double r = REAL(_this)[0]; if((double)((int) r) == r) _this = coerceVector(_this, INTSXP);

This code does the following: If the vector type is REALSXP (which means numeric) then convert first member of vector to double r. Then cast r as integer and then double and if bytes are still same convert whole vector as INTSXP. 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() where double r = REAL(_this)[0]; is changed to double r = REAL(_this)[1]; and test whether c(1.5, 1) works now or not.



转载请标明出处:sprintf invalid format '%d'
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!