3 min read

`fct_lump`分箱使用方法

用R的help功能发现, 存在 forcats::fct_lump。 因此安装这个包或者tidyverse包,然后library()调用函数。

举个例子。

library(tidyverse)
x <- factor(rep(LETTERS[1:9], times = c(40, 10, 5, 27, 1, 1, 1, 1, 1))) %>% as.tibble()
## Warning: `as.tibble()` is deprecated as of tibble 2.0.0.
## Please use `as_tibble()` instead.
## The signature and semantics have changed, see `?as_tibble`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
# x %>% head()
# x %>% str()
table(x)
## x
##  A  B  C  D  E  F  G  H  I 
## 40 10  5 27  1  1  1  1  1

这是样本例子。

x %>% 
  distinct()
## # A tibble: 9 x 1
##   value
##   <fct>
## 1 A    
## 2 B    
## 3 C    
## 4 D    
## 5 E    
## 6 F    
## 7 G    
## 8 H    
## 9 I
x %>% 
  mutate(value  = fct_lump(value)) %>% 
  distinct(value)
## # A tibble: 3 x 1
##   value
##   <fct>
## 1 A    
## 2 Other
## 3 D

这里可以看到x中只有一个column,叫做value。 对这个column进行覆盖,最后\(level = B, C, E, F, G, H, I \to Other\)

作用过程如下:

fct_lump(f, n, prop, other_level = "Other", ties.method = c("min",
  "average", "first", "last", "random", "max"))

other_level = "Other"决定了合并level的新命名,默认为Other,这里可以修改的。

其中n, prop确定了被合并的条件。

具体地,

x <- factor(letters[rpois(100, 5)]) %>% 
  as.tibble()
x
## # A tibble: 100 x 1
##    value
##    <fct>
##  1 e    
##  2 e    
##  3 c    
##  4 d    
##  5 g    
##  6 e    
##  7 j    
##  8 d    
##  9 f    
## 10 d    
## # ... with 90 more rows
x <- factor(letters[rpois(100, 5)])
table(x)
## x
##  a  b  c  d  e  f  g  h  i  j  o 
##  5  4 14 12 22 13 14  8  4  3  1
fct_lump(x, n = 3) %>% table()
## .
##     c     e     g Other 
##    14    22    14    50

n = 3表示只能保留三个level,其余都是Other

x %>% table()/length(x)
## .
##    a    b    c    d    e    f    g    h    i    j    o 
## 0.05 0.04 0.14 0.12 0.22 0.13 0.14 0.08 0.04 0.03 0.01
fct_lump(x, prop = 0.1) %>% table()/length(x)
## .
##     c     d     e     f     g Other 
##  0.14  0.12  0.22  0.13  0.14  0.25

prop = 0.1设定了\(\leq 0.1\)密度的,都是Other

以上是选多数的,下面可以使得多数分解,少数保留。

fct_lump(x, n = -3) %>% table()/length(x)
## .
##     b     i     j     o Other 
##  0.04  0.04  0.03  0.01  0.88
fct_lump(x, prop = -0.1) %>% table()/length(x)
## .
##     a     b     h     i     j     o Other 
##  0.05  0.04  0.08  0.04  0.03  0.01  0.75

可以看到加上了-号后,多数被分解了,临界条件没有变。

最后说下如何批量分箱。

z = data_frame(
  `x` = x,
  `y` = x
)
## Warning: `data_frame()` is deprecated as of tibble 1.1.0.
## Please use `tibble()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_warnings()` to see where this warning was generated.
z %>% head()
## # A tibble: 6 x 2
##   x     y    
##   <fct> <fct>
## 1 b     b    
## 2 g     g    
## 3 e     e    
## 4 e     e    
## 5 g     g    
## 6 c     c
z %>% 
  mutate_at(vars(x,y), fct_lump, n = 3) %>% 
  head()
## # A tibble: 6 x 2
##   x     y    
##   <fct> <fct>
## 1 Other Other
## 2 g     g    
## 3 e     e    
## 4 e     e    
## 5 g     g    
## 6 c     c

mutate_at中使用vars(x,y)选择需要批量修改的变量, fct_lump第二个参数就是我们的分箱函数, n = 3第三个参数就是分箱函数里面的参数, 直线思维,机智的一笔。