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

    xiaoxiao2025-08-21  7

    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
    转载请注明原文地址: https://ju.6miu.com/read-1301882.html
    最新回复(0)