8.1 幽灵(no.1~no.10)
8.1.1 R和S+的不同之处
R和S+有大量的不同之处。在R官网的FAQ板块已经说明(http://cran.r-project.org/faqs.html)。一部分,但不是所有的,也被提及。
8.2.2 包的功能
假设你看到了一条命令然后你想试试它,比如:
fortune('dog')
你试了一下得到了以下信息:
Error: could not find function "fortune"
当然的,你会认为你安装的R版本是坏的。我没有证据证明你的安装不是坏的,但更可能的原因是你当前的R版本没有安装包含这个函数fortune的包。你可以试试:
require(fortune)
于是你又得到了这条信息:
Error in library(package, ...) :
there is no package called ’fortune’
这个问题是你需要安装这个包到你的计算机上。如果你的计算机已经连接网络,你可以运行这条命令:
install.packages(’fortune’)
在这些提示之下,你会得到:
Warning message:
package ’fortune’ is not available
现在的问题是我们写错了包的名字。大写和拼写是非常重要的。正确的命令是:
install.packages(’fortunes’)
require(fortunes)
fortune(’dog’)
包的安装只需一次;在每一个项目中,当你需要使用某个函数是,包含这个函数的包都需要被安装。
命令:
library()
向你展示在你的标准安装路径下的R包。
8.1.3 优先级
假定代码会按照预期执行是一种罪恶。下述命令明确地准备生成从1到小于n的序列。
1:n-1
从上述示例,你应该会推断出这不是你得到的结果。
这是一种制造相似错误的方法:
10^2:6
如果你执行:
-2.3 ^ 4.5
你将会得到一个令你愉快的数字。如果你执行:
x <- -2.3
x ^ 4.5
你将会得到 not-a-number,也就是NAN。当然你或许会想到这两种方式的命令是一样的啊,其实它们并不是-操作符优先级又一次来捣鬼了。如果你真的需要后一种方式的操作,你可以这样做:
as.complex(x) ^ 4.5
请重视操作符优先级的问题吧。如果你不是很确定,括号可以强力执行你想要的命令。你可以查看R的优先级列表:
?Syntax
8.1.4 缺失值的相等问题
用下述命令来检验x中的缺失值几乎是不可能的:
x == NA
为什么不呢?
这是一个小提示:
3 == c(3, 1, 3, NA)
要检验,用:
is.na(x)
8.1.5 检验NULL
同样的,函数is.null可以检验一个对象是否为NULL。
> xnull <- NULL
> xnull == NULL
logical(0)
> xnotnull <- 42
> xnotnull == NULL
logical(0)
> is.null(xnull)
[1] TRUE
然而,人们经常检查对象的长度是否为零来判断—NULL并不是唯一的长度为零的对象。
> is.null(numeric(0))
[1] FALSE
8.1.6 成员
对于8==8操作我们期望来检查一个向量中的元素是否属于另外一个向量。如果幸运的话你会它会工作,但是一般情况下不会。(事实上,如果你创造了一个函数并且它正常运行你将是不幸的—你将会错过你造成的bug。)
> x1 <- 10:1
> x1 == c(4, 6)
[1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE
上面的命令并不能给你在x1中和4,6相等的位置。
下述情况下,使用8%in%:
> x1 %in% c(4, 6)
[1] FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
8.1.7 多重测试
如果你想做一个多重测试,你不能简略。以上一节的x1为例:
> x1 == 4 | 6
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> x1 == (4 | 6)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
接下来我们讨论在这两个命令里边到底发生了什么。这对你自己去发现问题来说是一个好的经验。
但是首先,我们实际上想要的操作是这样的:
> x1 == 4 | x1 == 6
[1] FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
或者(最好是更通用的方法):
> x1 %in% c(4, 6)
[1] FALSE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
现在,我们的彩蛋尝试做了些什么呢?
x1 == 4 | 6
和这个是等价的:
(x1 == 4) | 6
(两个命令会得到相同的答案)。最后一个命令和下述命令相同:
6 | (x1 == 4)
既然”or”是可交换的。8|8操作会强制参数变为逻辑值。任何非零数都会强制变为TRUE,因此所有结果的元素都将会是TRUE因为6已经被强制变为TRUE.
其他的一些命令会有不同的结果但是仍然遵从相似的强制转换。
4 | 6
和 下述命令相同:
TRUE | TRUE
最后结果即TRUE。因此R将会被问:
x1 == TRUE
在这种情况下,‘==’不会强制转换对象为逻辑值,而是转换为更加通用的类型:数值型。TRUE被强制转换为1。
8.1.8 强制转化
自动强制类型转换是一件好的事情。然而,它也会产生意外。下边是一个强制类型转换的列表—最具体到最不具体。
modes <- c('logical', 'numeric', 'complex', 'character')
modarr <- array(vector('list', 16), c(4, 4), list(modes, modes))
for(i in 1:4)
for(j in 1:4)
{
modarr[[i, j]] <- c(vector(modes[i], 0), vector(modes[j], 0))
}
> modarr
logical numeric complex character
logical Logical,0 Numeric,0 Complex,0 Character,0
numeric Numeric,0 Numeric,0 Complex,0 Character,0
complex Complex,0 Complex,0 Complex,0 Character,0
character Character,0 Character,0 Character,0 Character,0
这个示例并没有将numeric的interger类型加入进来。intergers在logical和(通用)numeric之间。你极不可能去关心(甚至知道)一个对象是以interger或者更加通用的numeric类型来存储的。
下边是一份完整的从最具体到最不具体的自动转换(存储)模式。
- logical
- integer
- numeric
- complex
- character
评论:这个示例中使用的matrix是一个list。注意到在matrix中使用’[[‘,一些使用者在偶然的情况下的到这样的matrix—一个或许会困惑你的事件。
8.1.9 强制转换下的比较
当你在有强制类型转换的地方做比较时,当心点:
> 50 < ’7’
[1] TRUE
8.1.10 在正确的地方放置括号
你想要将括号放置在正确的地方,下面的就是你期望的操作:
> length(mylist != 1)
Error: (list) object cannot be coerced to double
> length(mylist) != 1
[1] TRUE
在这个示例中我们是幸运地得到了一个错误信息所以我们就会知道有地方出问题了。