簡體   English   中英

按模式重新排序因子水平

[英]Reorder factor levels by pattern

我有一個因素可以識別調查數據集中的地層。 我想重新排序因素,使某些字符模式排在其他字符模式之前。

例如,我有一個混合因素,它表明性別、年齡和教育:

my_factor <- factor(levels=c(1:8),
                    labels=c("Male-18_34-HS","Female-35_49-HS",
                             "Male-18_34-CG", "Female-18_34-CG",
                             "Male-35_49-HS", "Male-35_49-CG",
                             "Female-18_34-HS", "Female-35_49-CG"),
                    ordered=TRUE)

我希望首先按所有女性類別訂購,然后按正確順序排列年齡類別,然后按正確順序排列教育類別。 我可以通過forcats::fct_relevel獲得大部分內容:

forcats::fct_relevel(my_factor, sort)

ordered(0)
8 Levels: Female-18_34-CG < Female-18_34-HS < Female-35_49-CG < Female-35_49-HS < Male-18_34-CG < Male-18_34-HS < ... < Male-35_49-HS

但是教育類別的順序是錯誤的。 有沒有辦法確保“HS”出現在“CG”之前但保持性別和年齡組的順序相同?

您可以制作參考表,按列因子級別排列:

library(dplyr)
library(tidyr)

ref <- tibble(key = c("Male-18_34-HS","Female-35_49-HS",
                      "Male-18_34-CG", "Female-18_34-CG",
                      "Male-35_49-HS", "Male-35_49-CG",
                      "Female-18_34-HS", "Female-35_49-CG"))

ref <- separate(ref, key, into = c("gender", "age", "education"), sep = "-", remove = FALSE) %>%
  mutate(across("gender", factor, c("Female", "Male")),
         across("age", factor, c("18_34", "35_49")),
         across("education", factor, c("HS", "CG"))) %>%
  arrange(gender, age, education)

然后申請:

factor(d, levels = ref$key)

您可以通過編程方式創建所需的因子水平。

lvls <- do.call(paste, c(tidyr::expand_grid(
           c('Female', 'Male'), c('18_34', '35_49'), c('HS', 'CG')), sep = '-'))
lvls
#[1] "Female-18_34-HS" "Female-18_34-CG" "Female-35_49-HS" "Female-35_49-CG"
#[5] "Male-18_34-HS"   "Male-18_34-CG"   "Male-35_49-HS"   "Male-35_49-CG"

您可以將此lvls用作factor調用中的級別。

您可以使用str_split拆分標簽,對生成的列表進行排序,並相應地重建級別:

lvl <- do.call(rbind,stringr::str_split(levels(my_factor),'-'))
lvl <- apply(lvl[order(lvl[,1],lvl[,2],lvl[,3]),],1,paste0,collapse='-')
my_factor <- factor(my_factor,levels = lvl)

levels(my_factor)
#> [1] "Female-18_34-CG" "Female-18_34-HS" "Female-35_49-CG" "Female-35_49-HS"
#> [5] "Male-18_34-CG"   "Male-18_34-HS"   "Male-35_49-CG"   "Male-35_49-HS"
dft<-c("Male-18_34-HS","Female-35_49-HS", "Male-18_34-CG", "Female-18_34-CG", "Male-35_49-HS", "Male-35_49-CG", "Female-18_34-HS", "Female-35_49-CG")

gender<-unlist(lapply(dft, FUN=function(x) str_split(x,'-')[[1]][1]))
age<-unlist(lapply(dft, FUN=function(x) str_split(x,'-')[[1]][1]))
ed<-unlist(lapply(dft, FUN=function(x) str_split(x,'-')[[1]][3]))

order_f<-order(gender,age,sort(ed,decreasing = T))

my_factor <- factor(levels=c(1:8),
                    labels=dft[order_f],
                    ordered=TRUE)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM