关键词:R
当你已经很熟悉一门语言,也许仍然会时不时碰到“哇,怎么会这样?”的时刻。因为总会有一些边边角角是你不曾留意的。
今天我们通过两个示例来一窥R的边角。 首先是:
代码语言:javascript复制>sqrt(2)^2 == 2; 2 sqrt(2)^2 == 2 2
[1] FALSE
[1] TRUE
怎么会这样?不应该都是TRUE吗?先不急,我们接着看:
代码语言:javascript复制>sqrt(2)^2 - 2; (2 sqrt(2)^2) - (2 2)
[1] 4.440892e-16
[1] 0
有没有看到,在R中涉及到浮点数的计算是很奇特的,这个结果也可以解释为什么最上面的结果不都是TRUE了。
那怎样才能避免这样令人迷惑不确定的结果呢?R的文档里有一段是这样说的:
"For numerical and complex values, == and != do not allow for the finite representation of fractions, nor for rounding error. Using all.equal() with identical() is almost always preferable."
翻译过来就是说,涉及到数值的判断,最好使用 all.equal() 函数以及 identical() 函数。以上面的示例为例:
代码语言:javascript复制>identical(all.equal(sqrt(2)^2, 2), TRUE)
[1] TRUE
或者更简单地:
代码语言:javascript复制>all.equal(sqrt(2)^2, 2)
[1] TRUE
接下来是第二个示例,我们来看:
代码语言:javascript复制c(1,0) (-1:4)
[1] 0 0 2 2 4 4
怎么会这样,也许你又要这样问。原因就在于R文档里的这一段话:
"The ' ' operator returns vectors containing the result of the element by element operations and the elements of shorter vectors are recycled as necessary."
翻译过来就是:当两个向量相加时,如果长度不一样,那么首先将短的那个向量内的元素循环,直至其长度与长向量一样,再将两个向量的元素一一相加。
什么意思呢?就以上面的语句为例,c(1,0)长度为2,(-1:4)长度为6,两个向量一长一短,要先将短的那个向量扩充,即c(1,0)向量中的元素1和0循环3次,变成c(1,0,1,0,1,0),目的是使其向量长度变成6。紧接着就是两个向量元素的一一相加,即第一个向量的第i个元素与第二个向量的第i个元素相加(i=1,2,…6)。
有点啰嗦哈,不过相信你已经懂了。其实c(1,0) (-1:4)就相当于c(1,0,1,0,1,0) (-1:4),两者的结果是一样的:
代码语言:javascript复制>c(1,0,1,0,1,0) (-1:4)
[1] 0 0 2 2 4 4
温故而知新,谢谢大家看此文章!