![](/img/trans.png)
[英]Conditionally change values in some rows using existing factor levels, possibly in dplyr
[英]Conditionally replace levels of factor variable using dplyr
我知道如何使用 dplyr/tidyr 有条件地替换变量的级别。 这是一些玩具数据(真实的数据集更大更复杂):
dat <- data.frame(animal=c("cat", "cat", "dog", "cat"),
size=c("big", "big", "big", "small"))
newdata <- dat %>% mutate(newanimal=replace(animal, animal=='cat' & size=='big', "fatcat"))
而且我不断收到“无效的因子水平,生成了 NA” - 为什么?,这些是因子变量。 dataframe 中存在“猫”和“大”的具体组合? 为什么我会收到此错误?
正如@camille 提到的,一旦你有了一个因素,它就会被锁定,如果你引入新的“条目”,它就会变成 NA。
例如:
x <- factor(letters[1:3])
x[3] = "d"
Warning message:
In `[<-.factor`(`*tmp*`, 3, value = "d") :
invalid factor level, NA generated
x
[1] a b <NA>
Levels: a b c
摆脱这种情况的唯一方法是先将其转换为字符并替换:
newdata <- dat %>% mutate(newanimal=replace(as.character(animal), animal=='cat' & size=='big', "fatcat"))
newdata
animal size newanimal
1 cat big fatcat
2 cat big fatcat
3 dog big dog
4 cat small cat
您的新列现在是一个字符,但如果需要,您可以随时将其转换回一个因子。
str(newdata)
'data.frame': 4 obs. of 3 variables:
$ animal : Factor w/ 2 levels "cat","dog": 1 1 2 1
$ size : Factor w/ 2 levels "big","small": 1 1 1 2
$ newanimal: chr "fatcat" "fatcat" "dog" "cat"
tidyverse 中的另一个选项是使用forcats::fct_expand
添加新级别,然后 pipe 将此向量放入原始replace
中,现在将按预期工作。 新变量是一个因素,不需要进一步转换(假设您想要的 output 是一个因素)。
library(tidyverse)
dat <- dat %>%
mutate(newanimal = fct_expand(animal, "fatcat") %>%
replace(., animal == "cat" & size == "big", "fatcat")
)
glimpse(dat)
Observations: 4
Variables: 3
$ animal <fct> cat, cat, dog, cat
$ size <fct> big, big, big, small
$ newanimal <fct> fatcat, fatcat, dog, cat
如果您经常使用这种因子替换,您可以编写自己的帮助程序 function:
replace_fct <- function(x, list, values) {
.x = forcats::fct_expand(x, unique(values))
replace(.x, list, values)
}
然后做:
dat %>%
mutate(newanimal = replace_fct(animal, animal == "cat" & size == "big", "fatcat")
)
你可以试试这个
library(tidyverse)
dat <- tibble(animal = c("cat","dog","cat","dog","dog","dog"),
size = c("big", "small", "big", "big", "big","big"))
dat %>% mutate(new_animal = ifelse(animal=='cat' & size=='big','fatcat',animal) ) %>%
mutate_if(is.character, as.factor)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.