[英]sprintf invalid format '%d'
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. 首先,
%d
代表整数。 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). 如果可能,vector参数将被回收,但如果它是
c(1.5, 1)
,当sprintf()
尝试用1.5替换%d
(这不是整数)时,它将失败。
I thought it might be related to the fact that in R both integer and double are numeric mode, for example: 我认为这可能与以下事实有关:在R中,integer和double都是数字模式,例如:
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. 因此,两个向量应存储为double。 More info about vector in R language definition and in the documentation for
? numeric
有关R语言定义和文档中的向量的更多信息
? numeric
? numeric
: ? numeric
:
The potential confusion is that R has used mode "numeric" to mean 'double or integer'"
潜在的混淆是R使用“数字”模式来表示“双重或整数”
I might have found the lines in the underlying C code which explain what is going on: 我可能已经在底层的C代码中找到了解释发生了什么的行:
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
. 此代码执行以下操作:如果向量类型为
REALSXP
(表示数字),则将向量的第一个成员转换为double r
。 Then cast r
as integer and then double and if bytes are still same convert whole vector as INTSXP
. 然后将
r
为整数然后加倍,如果字节仍然相同, INTSXP
整个向量转换为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];
为了测试这个假设,可以使用自定义
sprintf()
编译R,其中double r = REAL(_this)[0];
is changed to double r = REAL(_this)[1];
改为
double r = REAL(_this)[1];
and test whether c(1.5, 1)
works now or not. 并测试
c(1.5, 1)
是否现在有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.