使用具有正则表达式匹配的单个函数重新编码,折叠和顺序因子级别

问题描述 投票:2回答:1

我发现在R中操纵因子变量过于复杂。清洁因素时我经常想做的事情包括:

  • 度假级别 - 不仅可以设置参考类别,还可以将所有级别放在汇总表的逻辑(非字母顺序)中。 x <- factor(x, levels = new.order)
  • 重新编码/重命名因子级别 - 简化名称和/或将多个类别折叠为一个组。对于levels(x) <- new.levels(x)plyr::revalue的一对一重新编码,请参阅hereherecar::recode可以在单个语句中执行几个一对多匹配,但不支持正则表达式匹配。
  • 丢弃级别 - 不只是丢弃未使用的级别,而是将某些级别设置为丢失。 (例如那些有错误代码的人)。 x <- factor(as.character(x), exclude = drop.levels)
  • 添加级别 - 显示零计数的类别。

最棒的是拥有一个可以同时完成上述所有操作的功能,允许模糊(正则表达式)匹配用于重新编码和丢弃因子,可以在其他函数中使用(例如.lapplydplyr::mutate),并且具有简单的功能(一致的)语法。

我已经在下面发布了我最好的尝试作为答案,但如果我错过了已经存在的功能或者代码可以改进,请告诉我。

编辑

我已经知道了forcats包,它是用于处理分类变量(因子)的字幕工具。该程序包有许多选项可用于求助级别('fct_infreq','fct_reorder','fct_relevel',...),重新编码/分组级别('fct_recode','fct_lump','fct_collapse'),丢弃级别('fct_recode') ),并添加级别('fct_expand')。但是,迄今为止还没有支持正则表达式匹配。

r regex r-factor
1个回答
0
投票

这是我最好的尝试。

xfactor <- function(x, replace = NULL, drop = FALSE, ignore.case = FALSE, ...) {

  # Coerce to factor if not already (incorporating standard factor arguments)
  if (!is.factor(x))
    x <- factor(x, ...)

  if (!is.null(replace)) {

    # Recode factor levels
    if (!is.null(names(replace))) {
      names(replace)[names(replace) == ""] <- replace[names(replace) == ""]
      levels.tmp <- levels(x)
      for(i in seq_along(replace)) 
        levels.tmp[grepl(replace[i], levels.tmp, ignore.case = ignore.case)] <- names(replace)[i]
      levels(x) <- levels.tmp
      replace <- names(replace) 
    }

    # Reorder factor levels 
    if (drop == TRUE)
      # Drop levels not included in replace statement
      levels.new <- replace
    else 
      # Reorder levels so those in replace statment come first
      levels.new <- c(replace, setdiff(levels(x), replace))
  }

  else 
    levels.new <- levels(x)

  # Drop all levels listed in drop statement (converting vectors to regex expressions)  
  if (!is.logical(drop)) {
    levels.new <- levels.new[!grepl(paste(drop, collapse = "|"), levels.new)]       
  }

  # Output factor
  return(factor(x, levels = levels.new))
}

创建示例因素

x <- factor(c("dogfish", "rabbit","catfish", "mouse", "dirt"))
levels(x)
[1] "catfish" "dirt"    "dogfish" "mouse"   "rabbit" 

可以通过将未命名的向量传递给replace语句来重新排序因子级别。未包含在替换语句中的级别将移动到最后或删除。

xfactor(x, replace = c("mouse", "rabbit"))
[1] dogfish rabbit  catfish mouse   dirt   
Levels: mouse rabbit catfish dirt dogfish

xfactor(x, replace = c("mouse", "rabbit"), drop = TRUE)
[1] <NA>   rabbit <NA>   mouse  <NA>  
Levels: mouse rabbit

可以通过将命名向量传递给replace语句来重新编码,折叠和排序因子级别。其中矢量名称是新的因子级别,矢量值是旧级别的正则表达式。重复的新级别将被折叠。

xfactor(x, replace = c("Sea" = "fish", "Land" = "rab|mou"))
[1] Sea  Land Sea  Land dirt
Levels: Sea Land dirt    

可以通过将正则表达式(或向量)传递给drop语句来删除因子级别

xfactor(x, drop = "fish")
[1] <NA>   rabbit <NA>   mouse  dirt  
Levels: dirt mouse rabbit

该功能将在其他功能中使用

library(dplyr)
df <- data.frame(n = 1:5, x)
df %>%
  mutate(y = xfactor(x, replace = c("Sea" = "fish", "Land" = "rab|mou", "Air"), drop = "di"))
  n       x    y
1 1 dogfish  Sea
2 2  rabbit Land
3 3 catfish  Sea
4 4   mouse Land
5 5    dirt <NA>
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.