我发现在R中操纵因子变量过于复杂。清洁因素时我经常想做的事情包括:
x <- factor(x, levels = new.order)
levels(x) <- new.levels(x)
或plyr::revalue
的一对一重新编码,请参阅here或here。 car::recode
可以在单个语句中执行几个一对多匹配,但不支持正则表达式匹配。x <- factor(as.character(x), exclude = drop.levels)
最棒的是拥有一个可以同时完成上述所有操作的功能,允许模糊(正则表达式)匹配用于重新编码和丢弃因子,可以在其他函数中使用(例如.lapply
或dplyr::mutate
),并且具有简单的功能(一致的)语法。
我已经在下面发布了我最好的尝试作为答案,但如果我错过了已经存在的功能或者代码可以改进,请告诉我。
编辑
我已经知道了forcats
包,它是用于处理分类变量(因子)的字幕工具。该程序包有许多选项可用于求助级别('fct_infreq','fct_reorder','fct_relevel',...),重新编码/分组级别('fct_recode','fct_lump','fct_collapse'),丢弃级别('fct_recode') ),并添加级别('fct_expand')。但是,迄今为止还没有支持正则表达式匹配。
这是我最好的尝试。
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>