如何从tidyverse中的向量重新编码因子级别?

如何从tidyverse中的向量重新编码因子级别?,r,tidyverse,levels,recode,R,Tidyverse,Levels,Recode,考虑下面的数据集,有一个系数No有34个级别,我想根据newLvl MWE structure(list(No = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7

考虑下面的数据集,有一个系数
No
有34个级别,我想根据
newLvl

MWE

structure(list(No = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 
11L, 11L, 11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 
13L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 
15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 
17L, 17L, 17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 
19L, 19L, 19L, 19L, 20L, 20L, 20L, 20L, 20L, 20L, 21L, 21L, 21L, 
21L, 21L, 21L, 22L, 22L, 22L, 22L, 22L, 22L, 23L, 23L, 23L, 23L, 
23L, 23L, 24L, 24L, 24L, 24L, 24L, 24L, 25L, 25L, 25L, 25L, 25L, 
25L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 27L, 27L, 27L, 27L, 
27L, 27L, 28L, 28L, 28L, 28L, 29L, 29L, 29L, 29L, 29L, 29L, 30L, 
30L, 30L, 30L, 30L, 30L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 31L, 
32L, 32L, 32L, 32L, 32L, 32L, 33L, 33L, 33L, 33L, 33L, 33L, 34L, 
34L, 34L, 34L, 34L, 34L), .Label = c("1", "2", "3", "4", "5", 
"6", "7", "8", "10", "13", "14", "15", "16", "18", "19", "21", 
"22", "23", "24", "25", "27", "28", "29", "30", "31", "34", "38", 
"39", "40", "42", "47", "48", "49", "53"), class = "factor"), 
    Gender = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Female", 
    "Male"), class = "factor"), Age = c(23, 23, 23, 23, 23, 23, 
    39, 39, 39, 39, 39, 39, 30, 30, 30, 30, 30, 30, 30, 30, 24, 
    24, 24, 24, 24, 24, 24, 24, 18, 18, 18, 18, 18, 18, 23, 23, 
    23, 23, 23, 23, 23, 23, 26, 26, 26, 26, 26, 26, 23, 23, 23, 
    23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 30, 30, 30, 30, 
    30, 30, 20, 20, 20, 20, 20, 20, 25, 25, 25, 25, 25, 25, 25, 
    25, 23, 23, 23, 23, 23, 23, 23, 23, 38, 38, 38, 38, 38, 38, 
    22, 22, 22, 22, 22, 22, 29, 29, 29, 29, 29, 29, 21, 21, 21, 
    21, 21, 21, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 
    24, 24, 24, 24, 24, 24, 21, 21, 21, 21, 21, 21, 27, 27, 27, 
    27, 27, 27, 24, 24, 24, 24, 24, 24, 21, 21, 21, 21, 21, 21, 
    21, 21, 21, 21, 21, 21, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
    23, 23, 23, 23, 23, 21, 21, 21, 21, 27, 27, 27, 27, 27, 27, 
    34, 34, 34, 34, 34, 34, 26, 26, 26, 26, 26, 26, 26, 26, 28, 
    28, 28, 28, 28, 28, 39, 39, 39, 39, 39, 39, 26, 26, 26, 26, 
    26, 26)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-218L))
向量

oldLvl <- c(23, 24, 48, 47, 3, 15, 49, 16, 21, 42, 39, 29, 28, 8, 38, 7, 53, 2, 19, 10, 5, 22, 6, 18, 14, 31, 27, 34, 25, 13, 40, 30, 4, 1)
newLvl <- c(1:34)
试用版2

      df1 <- df %>%
  dplyr::mutate(Nbr = No) %>%
  dplyr::mutate(Nbr  =  forcats::fct_recode(Nbr, "23" = "1", "24" = "2", "48" = "3", "47" = "4", "3" = "5", "15" = "6", "49" = "7", "16" = "8", "21" = "9", "42" = "10", "39" = "11", "29" = "12", "28" = "13", "8" = "14", "38" = "15", "7" = "16", "2" = "17", "53" = "18", "19" = "19", "10" = "20", "5" = "21", "22" = "22", "6" = "23", "18" = "24", "14" = "25", "31" = "26", "27" = "27", "34" = "28", "25" = "29", "13" = "30", "40" = "31", "30" = "32", "4" = "33", "1" = "34"))
df1%
dplyr::突变(Nbr=No)%>%
dplyr::mutate(Nbr=forcats::fctêu recode(Nbr,23“=”1“,”24“=”2“,”48“=”3“,”47“=”4“,”3“=”5“,”6“,”49“=”7“,”16“=”8“,”21“,”21“,”11“,”29“,”12“,”28“,”13“,”8“,”14“,”38“,”15“,”7“,”16“,”2“,”17“,”53“,”18“,”19“,”19“,”10“,”20“,”5“,”21“,”22“,”24“,”24“,”24“,”24“,”24“,”24“,”24“,”24“,”24“,” = "25", "31" = "26", "27" = "27", "34" = "28", "25" = "29", "13" = "30", "40" = "31", "30" = "32", "4" = "33", "1" = "34"))
问题


上述两项试验均无效。如何使用
fct.*
系列将旧级别与新级别重新编码到新变量中,例如
Nbr

我们可以使用
向量
列表

library(dplyr)
df1 %>%
      mutate(Nbr = forcats::fct_recode(No,
            !!! setNames(as.character(oldLvl), newLvl)))
# A tibble: 218 x 4
#   No    Gender   Age Nbr  
#   <fct> <fct>  <dbl> <fct>
# 1 1     Male      23 34   
# 2 1     Male      23 34   
# 3 1     Male      23 34   
# 4 1     Male      23 34   
# 5 1     Male      23 34   
# 6 1     Male      23 34   
# 7 2     Male      39 18   
# 8 2     Male      39 18   
# 9 2     Male      39 18   
#10 2     Male      39 18   
# … with 208 more rows
库(dplyr)
df1%>%
变异(Nbr=forcats::fct_重新编码(否,
!!!设置名称(如.character(oldLvl)、newLvl)))
#A tibble:218x4
#无性别年龄Nbr
#       
#1男23 34
#2 1男23 34
#3 1男23 34
#4 1男23 34
#5 1男23 34
#6 1男23 34
#7 2男39 18
#82男39 18
#9 2男39 18
#102男39 18
#…还有208行

或者,如果我遵守
fct\u recode
函数的语法,我可以用下面的方法来完成。关键是
fct\u recode(.f,“new”=“old”)
而不是像我在帖子中第二次尝试失败那样

df1 <- df %>%
  dplyr::mutate(Nbr  =  forcats::fct_recode(No, "1" = "23",
                                            "2" = "24",
                                            "3" = "48",
                                            "4" = "47",
                                            "5" = "3",
                                            "6" = "15",
                                            "7" = "49",
                                            "8" = "16",
                                            "9" = "21",
                                            "10" = "42",
                                            "11" = "39",
                                            "12" = "29",
                                            "13" = "28",
                                            "14" = "8",
                                            "15" = "38",
                                            "16" = "7",
                                            "17" = "2",
                                            "18" = "53",
                                            "19" = "19", # switching is not needed
                                            "20" = "10",
                                            "21" = "5",
                                            "22" = "22", # switching is not needed
                                            "23" = "6",
                                            "24" = "18",
                                            "25" = "14",
                                            "26" = "31",
                                            "27" = "27", # switching is not needed
                                            "28" = "34",
                                            "29" = "25",
                                            "30" = "13",
                                            "31" = "40",
                                            "32" = "30",
                                            "33" = "4",
                                            "34" = "1"))


# A tibble: 218 x 4
#   No    Gender   Age Nbr  
#   <fct> <fct>  <dbl> <fct>
# 1 1     Male      23 34   
# 2 1     Male      23 34   
# 3 1     Male      23 34   
# 4 1     Male      23 34   
# 5 1     Male      23 34   
# 6 1     Male      23 34   
# 7 2     Male      39 17   
# 8 2     Male      39 17   
# 9 2     Male      39 17   
# 10 2     Male      39 17   
# … with 208 more rows
df1%
dplyr::mutate(Nbr=forcats::fct_recode(否,“1”=“23”),
"2" = "24",
"3" = "48",
"4" = "47",
"5" = "3",
"6" = "15",
"7" = "49",
"8" = "16",
"9" = "21",
"10" = "42",
"11" = "39",
"12" = "29",
"13" = "28",
"14" = "8",
"15" = "38",
"16" = "7",
"17" = "2",
"18" = "53",
“19”=“19”,不需要切换
"20" = "10",
"21" = "5",
“22”=“22”,不需要切换
"23" = "6",
"24" = "18",
"25" = "14",
"26" = "31",
“27”=“27”,不需要切换
"28" = "34",
"29" = "25",
"30" = "13",
"31" = "40",
"32" = "30",
"33" = "4",
"34" = "1"))
#A tibble:218x4
#无性别年龄Nbr
#       
#1男23 34
#2 1男23 34
#3 1男23 34
#4 1男23 34
#5 1男23 34
#6 1男23 34
#7 2男39 17
#82男39 17
#9 2男39 17
#102男39 17
#…还有208行

有趣的是,在这种情况下没有发出任何警告。

我想在我的数据集中保留“否”,并添加具有新记录级别的“Nbr”列。因此,
no
23的受试者的
Nbr
等于1,依此类推。您的第二次试验应该是
forcats::fct\u recode(no,“23”=“1”,
您是否也会在
f
中收到一条警告消息
未知级别:9、11、12、17、20、26、32、33
,知道原因吗?
df1 <- df %>%
  dplyr::mutate(Nbr  =  forcats::fct_recode(No, "1" = "23",
                                            "2" = "24",
                                            "3" = "48",
                                            "4" = "47",
                                            "5" = "3",
                                            "6" = "15",
                                            "7" = "49",
                                            "8" = "16",
                                            "9" = "21",
                                            "10" = "42",
                                            "11" = "39",
                                            "12" = "29",
                                            "13" = "28",
                                            "14" = "8",
                                            "15" = "38",
                                            "16" = "7",
                                            "17" = "2",
                                            "18" = "53",
                                            "19" = "19", # switching is not needed
                                            "20" = "10",
                                            "21" = "5",
                                            "22" = "22", # switching is not needed
                                            "23" = "6",
                                            "24" = "18",
                                            "25" = "14",
                                            "26" = "31",
                                            "27" = "27", # switching is not needed
                                            "28" = "34",
                                            "29" = "25",
                                            "30" = "13",
                                            "31" = "40",
                                            "32" = "30",
                                            "33" = "4",
                                            "34" = "1"))


# A tibble: 218 x 4
#   No    Gender   Age Nbr  
#   <fct> <fct>  <dbl> <fct>
# 1 1     Male      23 34   
# 2 1     Male      23 34   
# 3 1     Male      23 34   
# 4 1     Male      23 34   
# 5 1     Male      23 34   
# 6 1     Male      23 34   
# 7 2     Male      39 17   
# 8 2     Male      39 17   
# 9 2     Male      39 17   
# 10 2     Male      39 17   
# … with 208 more rows