我使用的因素很少,并且通常发现它们易于理解,但我经常对特定操作的细节模糊不清。目前,我正在编写/折叠类别,很少有观察到“其他”,我正在寻找一个快速的方法来做到这一点 - 我有一个或许20级的变量,但我有兴趣将它们中的一堆折叠成一个。 / p>
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()
调用,将它们全部枚举,每次类别几乎没有观察时将其归类为“其他”。
假设上面的top8
和top8_desc
是实际的前8位,那么将data$naics
声明为因子变量的最佳方式是什么,以便top8
中的值是否进行了正确编码,其他所有内容都被重新编码为other
?
答案 0 :(得分:6)
我认为最简单的方法是将不在前8位的所有naics重新标记为特殊值。
data$naics[!(data$naics %in% top8)] = -99
然后,您可以在将其转换为因子
时使用“排除”选项factor(data$naics, exclude=-99)
答案 1 :(得分: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'))
答案 2 :(得分: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)
答案 3 :(得分: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)
}