问题描述
我的数据具有理论上可能的水平,但不存在于数据中。我可以在base
R中轻松地表示这一点:
factor(c("test","test1","test2"),levels = c("test","test2","test3"))
如果我将其表化,我会看到test3
为0。这很好,并允许我编写函数,假设这些级别包括所有可能的结果,以防最终添加包含该级别的数据。
我无法在forcats
中复制它。首先,as_factor
函数不接受任何其他参数:
forcats::as_factor(c("test","test3"))
以下内容带有警告(如果可能的话,我希望在没有警告的情况下实现我的目标):
forcats::as_factor(c("test","test2")) %>% forcats::fct_recode(`test` = "test",`tests` = "test1",`tests` = "test2",`tests` = "test3")
Warning message:
UnkNown levels in `f`: test3
forcats
中有什么方法可以玩理论上已经存在但不一定在当时存在的关卡?
解决方法
如果我们想用factor
复制相同的行为,可以使用fct_expand
c("test","test1","test2") %>%
forcats::fct_expand(c("test","test2","test3"))
#[1] test test1 test2
#Levels: test test1 test2 test3
关于...
(as_factor
中的其他参数)的使用,实际上并没有使用
library(forcats)
methods(as_factor)
#[1] as_factor.character* as_factor.factor* as_factor.logical* as_factor.numeric*
现在,我们检查as_factor.character
的代码
getAnywhere(as_factor.character)
function (x,...)
{
structure(fct_inorder(x),label = attr(x,"label",exact = TRUE))
}
fct_inorder
仅接受'x',而不接受与...
一起传递的任何其他参数
在这里,我们可以直接使用fct_expand
来扩展levels
或factor
的{{1}}(转换为character
)
根据@Akrun的建议,我已经完成了我想要做的事情。请参见下面的示例:
test <- c("fruit","fruit","apple","drink","meat")
levels <- c(
`Fruit` = "fruit",`Fruit` = "apple",`Drink` = "drink",`Vegetable` = "vegetable",`Meat` = "meat"
)
factor(test) %>% table()
factor(test) %>% forcats::fct_expand(levels) %>% table()
factor(test) %>% forcats::fct_expand(levels) %>% forcats::fct_recode(!!!levels) %>% table()