使用具有正则表达式匹配

时间:2016-06-09 02:35:04

标签: r regex r-factor

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

  • 度假级别 - 不仅可以设置参考类别,还可以将所有级别放在逻辑(非字母顺序)的汇总表中。 x <- factor(x, levels = new.order)
  • 重新编码/重命名因子级别 - 简化名称和/或将多个类别合并为一个组。对于一对一重新编码levels(x) <- new.levels(x)plyr::revalue,请参阅herehere以获取示例。 car::recode可以在一个语句中执行多个一对多匹配,但不支持正则表达式匹配。

  • 丢弃级别 - 不只是丢弃未使用的级别,而是将某些级别设置为丢失。 (例如那些有错误代码的人)。 x <- factor(as.character(x), exclude = drop.levels)

  • 添加级别 - 显示零计数的类别。

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

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

修改

我已经了解了forcats包,其副标题为使用分类变量(因子)的工具。该套餐有多种选择来度假(&#39; fct_infreq&#39;,&#39; fct_reorder&#39;,&#39; fct_relevel&#39;,...),重新编码/分组级别(&#39; fct_recode&#39;,&#39; fct_lump&#39;,&#39; fct_collapse&#39;),删除级别(&#39; fct_recode&#39;),并添加级别(&#39; fct_expand&#39;) 。但目前还没有支持正则表达式匹配。

1 个答案:

答案 0 :(得分: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>