8.1 幽灵(no.21~no.30)
8.1.21 没有部分匹配的任务
部分匹配的一个最重要的副作用是当你做替换操作时使你变傻:
> ll2 <- list(aa=1:3, bb=4:6)
> ll2$b
[1] 4 5 6
> ll2$b <- 7:9
> ll2
$aa
[1] 1 2 3
$bb
[1] 4 5 6
$b
[1] 7 8 9
这也适用于数据框(毕竟数据框也是列表)。
8.1.22 cat和print
如果你要print一个没有名字的向量,那么在每一行的第一个元素前有一个索引指示。
> options(width=20)
> 1:10
[1] 1 2 3 4 5
[6] 6 7 8 9 10
另外,cat仅仅输出向量的内容:
> cat(1:10)
1 2 3 4 5 6 7 8 9 10>
注意到cat输出后没有新的一行,你需要自己加上:
cat(1:10, ’\n’)
print和cat根本的区别—cat实际上在解释它得到的字符串信息:
> xc <- ’blah\\blah\tblah\n’
> print(xc)
[1] "blah\\blah\tblah\n"
> cat(xc)
blah\blah blah
>
字符串是个双面手。一方面是字符串事实上所传递的信息(cat 输出)。另一方面是一个允许你看到所有字符的解释—这个字符串事实上是怎么构成的(print 输出)。不要将两者搞混。
重新读这个条目—它非常重要。怎么说呢,如果你不理解它,你将会浪费大量的实践在周围摸索,得不偿失。
8.1.23 反斜杠
反斜杠在R(Unix,C)中是转义字符。既然反斜杠并不代表反斜杠,那么就需要一种方法表示反斜杠。相当逻辑的这个方法就是反斜杠-反斜杠。
> cat(’\\’)
\>
有时文本需要在文本需要注释的地方加入反斜杠。在注释中每一对反斜杠变成了一个反斜杠。
有两个非常常见的字符带有反协防:\t是tab,\n是新的一行。表8.1展示了你经常会遇到的使用反斜杠的字符串。你可以看到整个列表:
?Quotes
注意到nchar()返回一个逻辑字符串的数量,并不是创造它们所需要的键盘敲击次数:
> nchar(’\\’)
[1] 1
8.1.24 国际化
并非所有人都在用同一种语言书写代码,这或许会事一些人感到惊奇。为了确保这个,R允许编码中包含latin1和UTF-8。
还有使用不同路径的可能性。路径可以影响代码存储命令。
多种编码格式和多种路径的选择自由使你需要花费数小时调整它们使自己迷惑。
更多信息:
> ?Encoding
> ?locales
8.1.25 Windows 下的路径
Quite unfortunately Windows uses the backslash to separate directories in paths.
Consider the R command:
attach(’C:\tmp\foo’)
相当不幸的是Window使用反斜线来区分路径中的目录。考虑以下命令:
attach(’C:\tmp\foo’)
这对字符串的双面性质造成困惑。事实上这个字符串包括:C,冒号,tab,m,p,formfeed,o,o。没有反斜线。这个字符串真正想说的是:
attach(’C:\\tmp\\foo’)
然而,在所有情况下R允许你在Windows路径中使用斜杠代替反斜杠—在内核中会被翻译:
attach(’C:/tmp/foo’)
如果你试图复制粘贴Windows路径进入R,你将会得到一个带有不被辨认的换页符警告的字符串。一种方法是将其粘贴到:
scan(’’, ’’, n=1)
8.1.26 引用
有三种类型的引号,一个山寨产业已经开发了包含字符串引用的R函数。表8.2展示了从不同方面考虑引用的函数列表。函数bquote()基本上是应用最广泛的—和函数substitute()很相似。
双引号和单引号—实质上的代名词—被用来限定字符型的字符串。如果限定字符串的引号就在字符串中,它需要用一个反斜杠来转义。
> ’"’
[1] "\""
一个反引号用来限定一个名字,通常这个名字打破一个对象的通用命名惯例。
> ’3469’
[1] "3469"
> '3469'
Error: Object "3469" not found
> '2' <- 2.5
> '2' + '2'
[1] 5
8.1.27 反引号
反引号在列表成员命名时有字母的情况下和一些不合法的名字上。没必要恐慌。
> ll3 <- list(A=3, NA=4)
Error: unexpected ’=’ in "ll3 <- list(A=3, NA="
> ll3 <- list(A=3, ’NA’=4)
> ll3 <- list(A=3, ’NA’=4, ’for’=5)
> ll3
$A
[1] 3
$ 'NA'
[1] 4
$ 'for'
[1] 5
> ll3$’for’
[1] 5
尽管成员名字带着反引号被打印出来,你可以使用常用的引号进行打印它们。一开始列表的初始化失败的原因是NA被认为是第二个成员—没有命名的数据。
8.1.28 消失的属性(I)
大多数强制转换类型的函数都会将对象的属性剥夺掉。比如:
as.numeric(xmat)
的结果将不会是一个矩阵了。下述命令既进行强制转换又会保持对象的属性:
storage.mode(xmat) <- ’numeric’
8.1.29 消失的属性(II)
> x5 <- 1
> attr(x5, ’comment’) <- ’this is x5’
> attributes(x5)
$comment
[1] "this is x5"
> attributes(x5[1])
NULL
下标查找几乎总是略去了所有属性。
如果你想保留属性的话,一个解决方法是为你的对象创建一个类,然后为你类的”[“写一个函数。
8.1.30 当空格出现问题
空格,或者没有空格,除了提供很好的阅读性之外,很少在R命令中有区别。
下面一例中空格将在R的解析器中造成麻烦。
x<-3
这将被解释为:
x <- 3
或者
x < -3
这将促使你使用空格键。使代码清晰最重要的方法是在"<-"
两边放置空格。不幸的是这并不会解决上面例子中的问题–在进行比较的时候空格是绝对需要的。