我有一个这样的数据框架,其中每一列都是分类编码:
> race <- factor(c(0,1,0,1,1))
> income <- factor(c(1,1,1,0,0))
> sex <- factor(c(1,1,1,3,2))
> df <- data.frame(race, income, sex)
> df
race income sex
1 0 1 1
2 1 1 1
3 0 1 1
4 1 0 3
5 1 0 2
如何在R dplyr中动态编程,使每一列都从0开始。例如,种族和收入不会改变,因为最低值已经是0。但性别需要改变,这样每个数字都减去1。
预期输出:
race income sex
1 0 1 0
2 1 1 0
3 0 1 0
4 1 0 2
5 1 0 1
理想情况下,解决方案将使用突变和交叉,但我似乎找不到解决方案。
df %>%
mutate(
across(everything(), as.numeric),
across(everything(), ~.-min(.)),
across(everything(), as.factor)
)
)
您可以将因子级别更改为数字,然后从中减去1。如果您想将其保持为类别,请将其更改回factor
。
使用across
将函数应用于多个列。
library(dplyr)
relevel_to_0 <- function(x) {
factor(as.integer(x) - 1)
}
df %>% mutate(across(.fns = relevel_to_0))
# race income sex
#1 0 1 0
#2 1 1 0
#3 0 1 0
#4 1 0 0
#5 1 0 1
您可以在制作因子向量时添加级别参数
race <- factor(c(0,1,0,1,1))
income <- factor(c(1,1,1,0,0))
sex <- factor(c(1,1,1,1,2), levels=0:2)
df <- data.frame(race, income, sex)
df[1,] <- 0
df
# race income sex
# 1 0 0 0
# 2 1 1 1
# 3 0 1 1
# 4 1 0 1
# 5 1 0 2
您可以使用以下代码:
library(tidyverse)
race <- factor(c(0,1,0,1,1))
income <- factor(c(1,1,1,0,0))
sex <- factor(c(1,1,1,3,2))
df <- data.frame(race, income, sex)
> df
race income sex
1 0 1 1
2 1 1 1
3 0 1 1
4 1 0 3
5 1 0 2
df %>% mutate_if(is.factor, .funs = ~ as.numeric(.)) %>% mutate_if(.predicate = ~ min(.) > 0, .funs = ~ as.factor( . - 1))
race income sex
1 0 1 0
2 1 1 0
3 0 1 0
4 1 0 2
5 1 0 1
或者将两个mutate_if
函数合并为一个:
df %>% mutate_if(.predicate = ~ (is.factor(.) & min(as.numeric(.)) > 0) , .funs = ~ as.factor( as.numeric(.) - 1))
race income sex
1 0 1 0
2 1 1 0
3 0 1 0
4 1 0 2
5 1 0 1