R中因子的折叠级别问题

R中因子的折叠级别问题,r,r-factor,R,R Factor,我有一个混乱的因子变量,它的级别比它应该的级别多。这些案例来自一项公开调查,许多参与者都写了错字,或者只是以不同的方式回答了类似的问题 这是代表我的问题的示例df: df <- data.frame(ID=seq(1:10), Nationality=c("espanol", "spaniol", "ESPANOL", "s

我有一个混乱的因子变量,它的级别比它应该的级别多。这些案例来自一项公开调查,许多参与者都写了错字,或者只是以不同的方式回答了类似的问题

这是代表我的问题的示例df:


df <- data.frame(ID=seq(1:10),
                 Nationality=c("espanol", "spaniol", "ESPANOL",
                               "spanish", "colombia", "Colombian",
                               "British", "brit", "ESPanol", "UK")
                               )
这就是我试图做的,以减少这10个人为水平的因素只有3(西班牙语,哥伦比亚语,英国),因为它应该是:

library(forcats) 
                              
levels(df$Nationality) <- fct_collapse(df$Nationality, Spanish = c("espanol", "spaniol", "ESPANOL",
                                                                  "spanish", "ESPanol"),
                                                       Colombian = c("colombia", "Colombian"),
                                                       British = c("British", "brit", "UK")
                                        )
在我使用的更大的数据集中,它也不起作用,但输出更糟糕,因为所有案例都变成了“西班牙语”,我没有任何线索说明为什么会发生这种情况

提前感谢您的帮助! 最好的
卢卡斯

你试过先把国籍作为一个因素吗

df <- data.frame(ID=seq(1:10),
                 Nationality=c("espanol", "spaniol", "ESPANOL",
                               "spanish", "colombia", "Colombian",
                               "British", "brit", "ESPanol", "UK")
)
library(forcats) 


df2 <- df %>% 
  mutate(Nationality = factor(Nationality)) %>% 
 mutate(Nationality = fct_collapse(Nationality, Spanish = c("espanol", "spaniol", "ESPANOL", "spanish", "ESPanol"),
                                       Colombian = c("colombia", "Colombian"),
                                       British = c("British", "brit", "UK")))



#more concise

mutate(across(Nationality, ~ fct_collapse(factor(.), 
Spanish = c("espanol", "spaniol", "ESPANOL", "spanish", "ESPanol"), 
Colombian = c("colombia", "Colombian"), 
British = c("British", "brit", "UK")
))) 
df%
突变(国籍=fct_崩溃(国籍,西班牙语=c(“espanol”,“spaniol”,“espanol”,“spaniol”,“espanol”,“Spanish”,“espanol”)),
哥伦比亚=哥伦比亚(“哥伦比亚”、“哥伦比亚”),
英国人=英国人(“英国人”、“英国人”、“英国人”))
#更简洁
突变(跨国籍,~fct_崩溃(因子(.),
西班牙语=c(“西班牙语”、“西班牙语”、“西班牙语”、“西班牙语”),
哥伦比亚=哥伦比亚(“哥伦比亚”、“哥伦比亚”),
不列颠=c(“不列颠”、“不列颠”、“英国”)
))) 

您是否尝试过先将国籍作为一个因素

df <- data.frame(ID=seq(1:10),
                 Nationality=c("espanol", "spaniol", "ESPANOL",
                               "spanish", "colombia", "Colombian",
                               "British", "brit", "ESPanol", "UK")
)
library(forcats) 


df2 <- df %>% 
  mutate(Nationality = factor(Nationality)) %>% 
 mutate(Nationality = fct_collapse(Nationality, Spanish = c("espanol", "spaniol", "ESPANOL", "spanish", "ESPanol"),
                                       Colombian = c("colombia", "Colombian"),
                                       British = c("British", "brit", "UK")))



#more concise

mutate(across(Nationality, ~ fct_collapse(factor(.), 
Spanish = c("espanol", "spaniol", "ESPANOL", "spanish", "ESPanol"), 
Colombian = c("colombia", "Colombian"), 
British = c("British", "brit", "UK")
))) 
df%
突变(国籍=fct_崩溃(国籍,西班牙语=c(“espanol”,“spaniol”,“espanol”,“spaniol”,“espanol”,“Spanish”,“espanol”)),
哥伦比亚=哥伦比亚(“哥伦比亚”、“哥伦比亚”),
英国人=英国人(“英国人”、“英国人”、“英国人”))
#更简洁
突变(跨国籍,~fct_崩溃(因子(.),
西班牙语=c(“西班牙语”、“西班牙语”、“西班牙语”、“西班牙语”),
哥伦比亚=哥伦比亚(“哥伦比亚”、“哥伦比亚”),
不列颠=c(“不列颠”、“不列颠”、“英国”)
))) 

以下是一些使用内置函数的解决方案:

解决方案1 此解决方案假定列
国籍
是一个字符变量

cases <- c(espanol = "Spanish", spaniol = "Spanish", ESPANOL = "Spanish", spanish = "Spanish", 
           British = "British", brit = "British", ESPanol = "Spanish", UK = "British",
           colombia = "Colombian", Colombian = "Colombian")

df$Nationality <- factor(cases[df$Nationality])

以下是一些使用内置函数的解决方案:

解决方案1 此解决方案假定列
国籍
是一个字符变量

cases <- c(espanol = "Spanish", spaniol = "Spanish", ESPANOL = "Spanish", spanish = "Spanish", 
           British = "British", brit = "British", ESPanol = "Spanish", UK = "British",
           colombia = "Colombian", Colombian = "Colombian")

df$Nationality <- factor(cases[df$Nationality])

或者
mutate\u-over(国籍,~fct\u-collapse(factor(.),西班牙语=…)
mutate\u*现在不推荐使用。变异(跨越(国籍,~fct_崩溃(因子(.),西班牙语=c(“espanol”,“spaniol”,“espanol”,“spaniol”,“espanol”,“Spanish”,“espanol”),哥伦比亚人=c(“哥伦比亚”,“哥伦比亚人”),英国人=c(“英国人”,“英国人”,“英国人”))对不起,这是一个拼写错误。(我确实知道
mutate.*
被弃用:
mutate.\u cross()
曾经存在过吗?)谢谢,这非常有效。然而,我很困惑。。。我从未明确地将变量声明为一个因子,但唯一的原因是,当使用
str(df$national)
时,输出告诉我这已经是一个因子了。这怎么可能?正如我在另一个答案中提到的,您的代码解决了这个问题。然而,问题从来不是它以前不是一个因子,较旧版本的R将其视为一个因子,并且使用相同的代码将其更改为因子之前不会给出预期的输出。我很好奇为什么我的代码不能正常工作,所以我从错误中吸取教训。谢谢或者
mutate\u-over(国籍,~fct\u-collapse(factor(.),西班牙语=…)
mutate\u*现在不推荐使用。变异(跨越(国籍,~fct_崩溃(因子(.),西班牙语=c(“espanol”,“spaniol”,“espanol”,“spaniol”,“espanol”,“Spanish”,“espanol”),哥伦比亚人=c(“哥伦比亚”,“哥伦比亚人”),英国人=c(“英国人”,“英国人”,“英国人”))对不起,这是一个拼写错误。(我确实知道
mutate.*
被弃用:
mutate.\u cross()
曾经存在过吗?)谢谢,这非常有效。然而,我很困惑。。。我从未明确地将变量声明为一个因子,但唯一的原因是,当使用
str(df$national)
时,输出告诉我这已经是一个因子了。这怎么可能?正如我在另一个答案中提到的,您的代码解决了这个问题。然而,问题从来不是它以前不是一个因子,较旧版本的R将其视为一个因子,并且使用相同的代码将其更改为因子之前不会给出预期的输出。我很好奇为什么我的代码不能正常工作,所以我从错误中吸取教训。谢谢谢谢,这也行。然而,问题似乎与我没有将
df$national
转换为factor相同。我不明白,因为正如
str(df$national)
函数所显示的那样,它应该已经是一个因素了。在描述它时,您谈到了因子变量,但在可再现的示例中,您提供了变量
国籍
作为字符。最好将其作为一个因素提供。如果你的变量已经是一个因子,那么你只需要解决方案2的第二部分。这是因为我不是很精通R,因为我很久以前还没有开始。我知道,除非另有规定,否则字符串在R中被视为字符,但我不明白为什么会发生这种情况:
str(df$national)
系数w/10级别“brit”,“British”,“British”,“5 8 7 9 3 4 2 1 6 10
这很可能是因为您使用的R版本早于4.0.0。。从R4.0.0开始,
data.frame
参数
stringsAsFactors
的默认值从
TRUE
更改为
FALSE
。运行
R.version.string
检查您正在使用的版本。如果它早于4.0.0(即,它以小于4的数字开头),则需要在创建数据时向
data.frame
函数添加一个附加参数
stringsAsFactors=FALSE
。设置为读取字符变量。。类似于` df continue:类似于
df$Nationality <- as.factor(df$Nationality)

levels(df$Nationality) <- list(Spanish = c("espanol", "spaniol", "ESPANOL", "spanish", "ESPanol"),
                               Colombian = c("colombia", "Colombian"),
                               British = c("British", "brit", "UK"))
#    ID Nationality
# 1   1     Spanish
# 2   2     Spanish
# 3   3     Spanish
# 4   4     Spanish
# 5   5   Colombian
# 6   6   Colombian
# 7   7     British
# 8   8     British
# 9   9     Spanish
# 10 10     British