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對象。創造這個對象的一個副本,然後改變副本中的構件,再將名字賦給這個副本。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章