代码之家  ›  专栏  ›  技术社区  ›  Brandon Bertelsen

相同的分组/重新编码因子数据帧

r
  •  7
  • Brandon Bertelsen  · 技术社区  · 14 年前

    假设我有一个这样的数据帧:

    df <- data.frame(a=letters[1:26],1:26)
    

    我想把因子a,b,c改为a。

    我该怎么做?

    5 回复  |  直到 14 年前
        1
  •  13
  •   A5C1D2H2I1M1N2O1R2T1    12 年前

    有人试过用这种简单的方法吗?它不需要特殊的包,只需要了解R如何处理因子。

    假设要重命名因子中的级别,获取它们的索引

    data <- data.frame(a=letters[1:26],1:26)
    lalpha <- levels(data$a)
    

    在本例中,我们假设要知道级别“e”和“w”的索引

    lalpha <- levels(data$a)
    ind <- c(which(lalpha == 'e'), which(lalpha == 'w'))
    

    现在我们可以使用这个索引来替换因子“a”的级别

    levels(data$a)[ind] <- 'X'
    

    如果你现在看看数据帧因子 a 会有一个X e w

    我让你试试结果。

        2
  •  14
  •   Gavin Simpson    14 年前

    一个选择是 recode() 包中函数 car :

    require(car)
    df <- data.frame(a=letters[1:26],1:26)
    df2 <- within(df, a <- recode(a, 'c("a","b","c")="a"'))
    > head(df2)
      a X1.26
    1 a     1
    2 a     2
    3 a     3
    4 d     4
    5 e     5
    6 f     6
    

    示例,其中 a 不是那么简单,我们将几个级别重新编码为一个级别。

    set.seed(123)
    df3 <- data.frame(a = sample(letters[1:5], 100, replace = TRUE),
                      b = 1:100)
    with(df3, head(a))
    with(df3, table(a))
    

    最后几行给出:

    > with(df3, head(a))
    [1] b d c e e a
    Levels: a b c d e
    > with(df3, table(a))
    a
     a  b  c  d  e 
    19 20 21 22 18
    

    现在让我们合并级别 e 进入水平 Z 使用 重新编码()

    df4 <- within(df3, a <- recode(a, 'c("a","e")="Z"'))
    with(df4, head(a))
    with(df4, table(a))
    

    它给出:

    > with(df4, head(a))
    [1] b d c Z Z Z
    Levels: b c d Z
    > with(df4, table(a))
    a
     b  c  d  Z 
    20 21 22 37
    

    在不拼写要合并的级别的情况下执行此操作:

    ## Select the levels you want (here 'a' and 'e')
    lev.want <- with(df3, levels(a)[c(1,5)])
    ## now paste together
    lev.want <- paste(lev.want, collapse = "','")
    ## then bolt on the extra bit
    codes <- paste("c('", lev.want, "')='Z'", sep = "")
    ## then use within recode()
    df5 <- within(df3, a <- recode(a, codes))
    with(df5, table(a))
    

    它给了我们同样的 df4 上图:

    > with(df5, table(a))
    a
     b  c  d  Z 
    20 21 22 37 
    
        3
  •  3
  •   Joshua Ulrich    14 年前

    你可以这样做:

    df$a[df$a %in% c("a","b","c")] <- "a"
    

    更新:更复杂的因素。

    Data <- data.frame(a=sample(c("Less than $50,000","$50,000-$99,999",
      "$100,000-$249,999", "$250,000-$500,000"),20,TRUE),n=1:20)
    rows <- Data$a %in% c("$50,000-$99,999", "$100,000-$249,999")
    Data$a[rows] <- "$250,000-$500,000"
    
        4
  •  2
  •   kohske    14 年前

    有两种方法。 如果你不想降低未使用的水平,即“b”和“c”,约书亚的解决方案可能是最好的。

    如果要删除未使用的级别,则

    df$a<-factor(ifelse(df$a%in%c("a","b","c"),"a",as.character(df$a)))
    

    levels(df$a)<-ifelse(levels(df$a)%in%c("a","b","c"),"a",levels(df$a))
    
        5
  •  0
  •   Brandon Bertelsen    9 年前

    这是所选答案的简化版本:

    我发现处理这个问题最简单的方法就是简单地通过查看因子级别,然后写下要覆盖的数字来覆盖它们。

    df <- data.frame(a=letters[1:26],1:26)
    levels(df)
    
    > [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" 
     "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
    
    levels(df$a)[c(1,2)] <- "c"
    summary(df$a)
    
    > c d e f g h i j k l m n o p q r s t u v w x y z 
      3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1