8.1 幽灵(no.31~no.40)

8.1 幽灵(no.31~no.40)

8.1.31 多重比较

0 < x < 1

看起来是个合理的方法来测试x是否在0和1之间。可R并不这么认为。R是这么想的:

0 < x & x < 1

8.1.32 命名覆盖

默认的T和F分别分配给TRUE和FALSE。然而,它们也可以被用来命名对象(S+中不可以)。你可以考虑一下建议:

  • 最好使用TRUE和FALSE,而不是T和F。
  • 最好不要使用T和F来给对象命名,以免和没有遵从建议1的情况而产生碰撞。

最好避免使用常用函数名字来命名对象。比如c和t。并且不要叫你的矩阵matrix:

fortune(’dog’)

通常情况下覆盖对象仅仅会造成困惑。但是,如果你将你自己的函数的名称覆盖到一个常用的函数上,无异于自杀。

> c <- function(x) x * 100
> par(mfrow=c(2, 2)) 
Error in c(2, 2) : unused argument(s) (2)

如果你遇到了一个极度奇怪的错误,可能就是名称覆盖的问题。在已经存在的情况下规避这个名称:

find(’c’)

如果你知道哪个函数出现了问题。可以这样查找具体错误:

conflicts(detail=TRUE)

另外一个可能的方法是使用--vanilla启动R。

8.1.33 排序

当函数sort()不能实现你所想要的排序功能时,函数order()或许可以助阵。函数order()使用场合:

  • 对矩阵的行或者数据框进行排序。
  • 对基于另外一个向量值的向量进行排序。
  • 打破与其他变量的关系。

8.1.34 sort.list()并不是适用于列表

不要认为sort.list()就是给列表排序。你个笨蛋。

> sort(as.list(1:20))
Error in sort.int(x, na.last = na.last, ...) :’x’ must be atomic
> sort.list(as.list(1:20))
Error in sort.list(as.list(1:20)) : ’x’ must be atomic Have you called ’sort’ on a list?

如果你想对你的列表进行排序,你需要构造你自己的函数去实现了。

8.1.35 搜索列表改组

attach和load在目的上非常相似,但效果上却不同。attach在搜索列表中新建了一个目录而load将所包含的内容全部加入到了全局环境中(搜索列表的第一位)。

通常情况下,attach是将组对象之间区分的好的方法。然而,如果你改变了工作目录并且需要一个已经存在的.RData,这时候load是你的选择。

下边是一个脚本(你不像要的):

  • 目录project1下存在一个.RData。
  • 你在其他目录下打开了一个R,并且将工作目录切换到project1。
  • 全局环境来自初始目录。
  • 你attach这个在project1下的.RData。
  • 你做了一些工作,退出并且保存了工作空间。
  • 你仅仅是擦拭了project1的原始.RData,丢失了刚才的数据。

8.1.36 source 和 attach 或者 load

attach和load都可以将R对象加入搜索列表。函数source也可以,但是在起点是以代码的形式创建对象而不是那个实际的对象。

你应该按照管理进行操作。R代码的扩展名是”.R”。其他扩展名包括”.q”,”.rt”,”.Rscript”。

R对象的文件扩展名包括”.rda”,”.RData”。

8.1.37 字符串不是名字(I)

如果你有一个包含一个对象名字的字符型字符串,并且你想得到这个对象,使用get():

funs <- c(’mean’, ’median’)
get(funs[2])(data)

如果你发现as.name()并且觉得这个可以解决你的问题,你是正确的但是得再进一步:

eval(as.name(funs[2]))(data)

8.1.38 获得一个构件

函数get()非常有用,但并不是千里眼。如果你这样:

get(’myobj$comp’)

它会认为你需要一个名字为”myobj$comp“的对象。如果你想要myobj中的comp构件,你需要这样:

get(’myobj’)$comp

8.1.39 字符串不是名字(II)

如果在一个列表中,你有一个你想提取的构件,它的名字是一个字符串形式,你不可以使用”$”,你需要使用”[[“:

> mylist <- list(aaa=1:5, bbb=letters)
> subv <- ’aaa’
> mylist$subv
NULL
> # the next three lines are all the same
> mylist$aaa
[1] 1 2 3 4 5
> mylist[[’aaa’]]
[1] 1 2 3 4 5
> mylist[[subv]]
[1] 1 2 3 4 5

8.1.40 字符串不是名字(III)

如果你使用paste()创造了一个是对象名字的字符串,你不可以在赋值的左边:

> paste(’x’, 1, sep=’’) <- 3:5
Error: Target of assignment expands to non-language object

但是assign可以这样:

for(i in 1:n) assign(paste(’obj’, i, sep=’.’), mylist[[i]])

警告:这样的操作会让你回到第三轮回(向量化失败—这是一个反向量化的操作)或者第六轮回的异教徒。

你可以看到get(),将”myobj$comp”作为名字并不会得到你想要的结果—它仅仅会创造一个非标准名字的对象而不是修改myobj的comp对象。创造这个对象的一个副本,然后改变副本中的构件,再将名字赋给这个副本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值