根据计数,折叠数据框中所有因子变量的因子级别

时间:2016-08-05 11:56:46

标签: r lapply

我想根据频率仅保留前2个因子级别,并将所有其他因素分组到其他中。我尝试了这个,但它没有帮助。

df=data.frame(a=as.factor(c(rep('D',3),rep('B',5),rep('C',2))), 
              b=as.factor(c(rep('A',5),rep('B',5))), 
              c=as.factor(c(rep('A',3),rep('B',5),rep('C',2)))) 

myfun=function(x){
    if(is.factor(x)){
        levels(x)[!levels(x) %in% names(sort(table(x),decreasing = T)[1:2])]='Others'  
    }
}

df=as.data.frame(lapply(df, myfun))

预期产出

       a b      c
       D A      A
       D A      A
       D A      A
       B A      B
       B A      B
       B B      B
       B B      B
       B B      B
  others B others
  others B others

2 个答案:

答案 0 :(得分:2)

这可能会有点混乱,但这是通过基础R的一种方法,

fun1 <- function(x){levels(x) <- 
                    c(names(sort(table(x), decreasing = TRUE)[1:2]), 
                    rep('others', length(levels(x))-2)); 
                    return(x)}

然而,上述功能需要首先重新排序,并且在评论中OP状态,正确的将是,

fun1 <- function(x){ x=factor(x, 
                     levels = names(sort(table(x), decreasing = TRUE))); 
                     levels(x) <- c(names(sort(table(x), decreasing = TRUE)[1:2]), 
                     rep('others', length(levels(x))-2)); 
                     return(x) } 

答案 1 :(得分:1)

感谢fct_lump()包中的forcats,这很容易。

fct_lump(df$a, n = 2)

# [1] D     D     D     B     B     B     B     B     Other Other
# Levels: B D Other

参数n控制要保留的最常见级别的数量,将其他级别集中在一起。