R:因子水平,重新编码为'其他'

问题描述 投票:11回答:4

我使用的因素很少,并且通常会发现它们易于理解,但我常常对特定操作的细节模糊不清。目前,我正在编写/折叠类别,很少有观察到“其他”,我正在寻找一个快速的方法来做到这一点 - 我有一个或许20级的变量,但我有兴趣将它们中的一堆折叠成一个。

data <- data.frame(employees = sample.int(1000,500),
                   naics = sample(c('621111','621112','621210','621310','621320','621330','621340','621391','621399','621410','621420','621491','621492','621493','621498','621511','621512','621610','621910','621991','621999'),
                                  100, replace=T))

以下是我感兴趣的级别,以及它们在不同向量中的标签。

#levels and labels
top8 <-c('621111','621210','621399','621610','621330',
         '621310','621511','621420','621320')
top8_desc <- c('Offices of physicians',
               'Offices of dentists',
               'Offices of all other miscellaneous health practitioners',
               'Home health care services',
               'Offices of Mental Health Practitioners',
               'Offices of chiropractors',
               'Medical Laboratories',
               'Outpatient Mental Health and Substance Abuse Centers',
               'Offices of optometrists')

我可以使用factor()调用,枚举它们,每次类别几乎没有观察时将其分类为“其他”。

假设上面的top8top8_desc是实际前8位,那么将data$naics声明为因子变量的最佳方法是什么,以便top8中的值被正确编码,其他所有内容都被重新编码为other

r r-factor
4个回答
6
投票

我认为最简单的方法是将不在前8位的所有naics重新标记为特殊值。

data$naics[!(data$naics %in% top8)] = -99

然后,您可以在将其转换为因子时使用“排除”选项

factor(data$naics, exclude=-99)

4
投票

你可以使用forcats::fct_other()

library(forcats)
data$naics <- fct_other(data$naics, keep = top8, other_level = 'other')

或者使用fct_other()作为dplyr::mutate()的一部分:

library(dplyr)
data <- mutate(data, naics = fct_other(naics, keep = top8, other_level = 'other')) 

data %>% head(10)
   employees  naics
1        420  other
2        264  other
3        189  other
4        157 621610
5        376 621610
6        236  other
7        658 621320
8        959 621320
9        216  other
10       156  other

请注意,如果未设置参数other_level,则其他级别默认为“其他”(大写“O”)。

相反,如果您只想将几个因素转换为“其他”,则可以使用参数drop代替:

data %>%  
  mutate(keep_fct = fct_other(naics, keep = top8, other_level = 'other'),
         drop_fct = fct_other(naics, drop = top8, other_level = 'other')) %>% 
  head(10)

   employees  naics keep_fct drop_fct
1        474 621491    other   621491
2        805 621111   621111    other
3        434 621910    other   621910
4        845 621111   621111    other
5        243 621340    other   621340
6        466 621493    other   621493
7        369 621111   621111    other
8         57 621493    other   621493
9        144 621491    other   621491
10       786 621910    other   621910

dpylr也有recode_factor(),你可以在其中设置.default参数,但有更多的级别进行重新编码,就像这个例子一样,可能很乏味:

data %>% 
   mutate(naices = recode_factor(naics, `621111` = '621111', `621210` = '621210', `621399` = '621399', `621610` = '621610', `621330` = '621330', `621310` = '621310', `621511` = '621511', `621420` = '621420', `621320` = '621320', .default = 'other'))

3
投票

迟到的

这是plyr::mapvalues的包装器,它允许一个remaining参数(你的other

library(plyr)

Mapvalues <- function(x, from, to, warn_missing= TRUE, remaining = NULL){
  if(!is.null(remaining)){
    therest <- setdiff(x, from)
    from <- c(from, therest)
    to <- c(to, rep_len(remaining, length(therest)))
  }
  mapvalues(x, from, to, warn_missing)
}
# replace the remaining values with "other"
Mapvalues(data$naics, top8, top8_desc,remaining = 'other')
# leave the remaining values alone
Mapvalues(data$naics, top8, top8_desc)

0
投票

我已经写了一个功能,可以对其他人有用吗?我首先以相对的方式检查,如果一个水平发生的数量低于基数的mp%。之后,我检查将最大级别数限制为ml。

ds是data.frame类型的数据集,我对cat_var_names中出现的所有列执行此操作。

cat_var_names <- names(clean_base[sapply(clean_base, is.factor)])

recodeLevels <- function (ds = clean_base, var_list = cat_var_names, mp = 0.01, ml = 25) {
  # remove less frequent levels in factor
  # 
  n <- nrow(ds)
  # keep levels with more then mp percent of cases
  for (i in var_list){
    keep <- levels(ds[[i]])[table(ds[[i]]) > mp * n]
    levels(ds[[i]])[which(!levels(ds[[i]])%in%keep)] <- "other"
  }

  # keep top ml levels
  for (i in var_list){
    keep <- names(sort(table(ds[i]),decreasing=TRUE)[1:ml])
    levels(ds[[i]])[which(!levels(ds[[i]])%in%keep)] <- "other"
  }
  return(ds)
}
© www.soinside.com 2019 - 2024. All rights reserved.