8.2 喀迈拉(no.1~no.10)

8.2 喀迈拉(no.1~no.10)

8.2.1 数字到因子到数字

一般情况下尽管因子不会涉及到数字,但是它们可以。在这种情况下,我们会有更多的困惑。

> as.numeric(factor(101:103))
[1] 1 2 3

如果你期望这样:

[1] 101 102 103

好耻辱啊。

如果你的因子代表数字,你要从因子里恢复这些数字,那么你需要一个曲线救国方案。

as.numeric(as.character(factor(101:103)))

稍微更有效,但难以记住的是:

as.numeric(levels(f))[f]

f是一个因子。

8.2.2 输出因子

在因子上使用函数cat()将仅仅输出核心数据:

> cat(factor(letters[1:5]))
1 2 3 4 5>

8.2.3 意外情况:数字变成因子

当使用read.table()或者此类函数,一列数字类型的数据被以因子的形式读入太常见了。如果na.strings 没有被合理地设置,如果在列上有一个假的入口,或者如果有其他很多的情况,就会发生。

这无异于一包炸药。

这些数据被认为是数字。事实上确实是数字(至少是排序的),但决然不是我们预期的数字。因此你可以使用这些可以“工作”的数据但只会产生完全的垃圾。

当处理这些数据,这样:

as.numeric(as.character(x))

保证你排除问题。如果x已经是一个正确的数字,那么这个除了浪费一点时间外别无副作用。如果x意外地是一个因子,那么这将会是正确的数字(最少在绝大多情况下—取决于它为什么称为因子可能是有一些错误的缺失值。)

8.2.4 剔除因子级别

> ff <- factor(c(’AA’, ’BA’, ’CA’))
> ff
[1] AA BA CA
Levels: AA BA CA
> ff[1:2]
[1] AA BA
Levels: AA BA CA

注意到即使在向量中仅仅有两个元素出现,这里仍然有三个级别。级别不会自动地被剔除通常是一个好的事情—因子有它可以包含的可能的级别而不是仅仅包含它已经包含的级别。

有时你想让那些被剔除的的级别不在出现。有几种方法:

> ff[1:2, drop=TRUE]
[1] AA BA
Levels: AA BA
> factor(ff[1:2])
[1] AA BA
Levels: AA BA

如果f0是已经含有那些你想剔除的没有用的级别,你可以:

f0 <- f0[drop=TRUE]

8.2.5 合并级别

我们已经知道,奇怪的事情将会在合并级别的时候发生。一个安全的方法是重新创建一个因子对象。下边我们把单个字母变为辅音分类:

> flet <- factor(letters[c(1:5, 1:2)])
> flet
[1] a b c d e a b
Levels: a b c d e
> ftrans <- c(a=’vowel’, b=’consonant’, c=’consonant’,d=’consonant’, e=’vowel’)
> fcv <- factor(ftrans[as.character(flet)])
> fcv
[1] vowel consonant consonant consonant vowel vowel consonant
Levels: consonant vowel

或许更常用的是合并一些级别,但是将其他的单独留下:

> llet <- levels(flet)
> names(llet) <- llet
> llet
 a   b   c   d   e
"a" "b" "c" "d" "e"
> llet[c(’a’, ’b’)] <- ’ab’
> llet
 a    b    c   d   e
"ab" "ab" "c" "d" "e"
> fcom <- factor(llet[as.character(flet)])
> fcom
[1] ab ab c d e ab ab
Levels: ab c d e

8.2.6 不要在因子上使用下标

> x6 <- c(s=4, j=55, f=888)
> x6[c(’s’, ’f’)]
s f
4 888
> x6[factor(c(’s’, ’f’))]
j s
55 4

8.2.7 不要在ifelse中使用因子

> ifelse(c(TRUE, FALSE, TRUE), factor(letters),factor(LETTERS))
[1] 1 2 3
> ifelse(c(TRUE, FALSE, TRUE), factor(letters), LETTERS)
[1] "1" "B" "3"

(回想一下,ifelse输出的长度总是第一个参数的长度。如果你期待第一个参数被复制,你最好不要。)

8.2.8 不要在c中使用因子

c(myfac1, myfac2)

仅仅给你整型代码的合成向量。毫无疑问可以书写对于因子的c的方法,但是会比较复杂—因子的级别不需要匹配。这将得不偿失。这是一个R不会过分有帮助的示例。对于手头的确定的情况,这样做组合是有道理的。

另一个没有对于因子的c函数的原因是c被用来其他可以简化对象的情况。

> c(matrix(1:4, 2))
[1] 1 2 3 4

c在因子上的操作和这个是一致的。

一个普遍好的方法是:

c(as.character(myfac1), as.character(myfac2))

或者对于上述表达式的更加相似的因子。另外一种可能的方法是:

unlist(list(myfac1, myfac2))

比如:

> unlist(list(factor(letters[1:3]), factor(LETTERS[7:8])))
[1] a b c G H
Levels: a b c G H

最后的解决方案对于已排序的因子不适用。

8.2.9 有序排序

当你在创建有序因子时需要主意了:

> ordered(c(100, 90, 110, 90, 100, 110))
[1] 100 90 110 90 100 110
Levels: 90 < 100 < 110
> ordered(as.character(c(100, 90, 110, 90, 100, 110)))
[1] 100 90 110 90 100 110
Levels: 100 < 110 < 90

自动排序是按照字符的字典顺序进行的。通常这是有意义的,但在这个案例中不适用。(注意排序或许取决于你的定位。)你总是可以指定级别以有一个直接的控制。

如果你试着去排序一个因子, 你也会遇到相同的问题。

8.2.10 标签和被剔除的级别

标签的数量和级别的数量必须相同。看起来是个好的规则。在函数中也是这样,但是没必要在最后。问题是有些值被剔除了。

> factor(c(1:4,1:3), levels=c(1:4,NA), labels=1:5)
Error in factor(c(1:4, 1:3), levels = c(1:4, NA), ... :
invalid labels; length 5 should be 1 or 4
> factor(c(1:4,1:3), levels=c(1:4,NA), labels=1:4)
[1] 1 2 3 4 1 2 3
Levels: 1 2 3 4
> factor(c(1:4,1:3), levels=c(1:4,NA), labels=1:5,exclude=NULL)
[1] 1 2 3 4 1 2 3
Levels: 1 2 3 4 5

当然我骗你了。标签的数量可以是1也可以是级别的数量:

> factor(c(1:4,1:3), levels=c(1:4,NA), labels=’Blah’)
[1] Blah1 Blah2 Blah3 Blah4 Blah1 Blah2 Blah3
Levels: Blah1 Blah2 Blah3 Blah4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值