0

当级别数低于 dplyr 的给定阈值时,我想将数值变量转换为因子。

这对于编码为数字“0/1”的二进制变量最有用。

示例数据:

threshold<-5

data<-data.frame(binary1=rep(c(0,1), 5), binary_2=sample(c(0,1), 10, replace = TRUE), multilevel=sample(c(1:4), 10, replace=TRUE), numerical=1:10)

> data
   binary1 binary_2 multilevel numerical
1        0        1          2         1
2        1        0          3         2
3        0        1          2         3
4        1        0          1         4
5        0        1          2         5
6        1        1          4         6
7        0        1          1         7
8        1        1          3         8
9        0        1          1         9
10       1        0          4        10

sapply(data, class)
   binary1   binary_2 multilevel  numerical 
 "numeric"  "numeric"  "integer"  "integer" 

我可以使用 mutate()、cross() 和 where() 轻松地将所有变量转换为因子,如下所示:

data<-data%>%mutate(across(where(is.numeric), as.factor))

> sapply(data, class)
   binary1   binary_2 multilevel  numerical 
  "factor"   "factor"   "factor"   "factor"

但是,对于 where() 函数,我找不到一种方法来改变多个条件,包括我的阈值参数。我想要这个输出:

sapply(data, class)
   binary1   binary_2 multilevel  numerical 
 "factor"  "factor"  "factor"  "integer"

尝试了以下方法,但失败了:

data%>%mutate(across(where(is.numeric & length(unique(.x))<threshold), as.factor))

错误信息:

Error: Problem with `mutate()` input `..1`.
x object '.x' not found
ℹ Input `..1` is `across(where(!is.factor & length(unique(.x)) < threshold), as.factor)`.
Run `rlang::last_error()` to see where the error occurred.

也许我不太了解cross() 和where()。欢迎提出建议。

附加问题:为什么在 is.factor 之前包含否定运算符 (!) 会在没有 (!) 的版本完全没问题时让我出错?

data<-data%>%mutate(across(where(!is.factor), as.factor))

错误:mutate()输入有问题..1。x 无效的参数类型 ℹ 输入..1across(where(!is.factor), as.factor). 运行rlang::last_error()以查看错误发生的位置。

4

2 回答 2

2

where.

library(dplyr)

data <- data %>% 
     mutate(across(where(~is.numeric(.) && n_distinct(.) < threshold), factor))

sapply(data, class)

#   binary1   binary_2 multilevel  numerical 
#  "factor"   "factor"   "factor"  "integer" 

要回答您的附加问题,!is.factor它不是像is.factor. 以与上述相同的方式使用该功能。

data %>% mutate(across(where(~!is.factor(.)), factor))
于 2021-03-31T03:11:55.377 回答
1

使用data.table

library(data.table)
data1 <- setDT(data)[, lapply(.SD, function(x) 
        if(is.numeric(x) && uniqueN(x) < threshold) factor(x) else x)]
于 2021-03-31T18:13:38.437 回答