r - 将 data.table 因子列转换为字符列的最快方法
问题描述
TL;DR:将 data.table 中的所有因子列转换为字符列的最快/最节省内存的方法是什么?
作为序言,我怀疑这个问题可能会在其他地方得到回答,我正在努力寻找任何确定的东西,所以如果有人能指出我正确的方向,我将不胜感激,就像一个详尽的答案一样。
我经常需要将所有 data.table 因子列转换为字符列。看到 Matt Dowle 建议在这个答案的评论set
中使用这个任务,我认为这是最快/最有效的方式。
但是,当我进行一些测试时,我对结果感到惊讶。方法如下:
测试数据生成
library(data.table)
set.seed(1234)
## Create a vector of 1 million 4 character strings
## with 456,976 possible unique values
DiverseSize <- 1e6
Diverse <- paste0(sample(LETTERS,DiverseSize,replace = TRUE),
sample(letters,DiverseSize,replace = TRUE),
sample(letters,DiverseSize,replace = TRUE),
sample(letters,DiverseSize,replace = TRUE))
## Create a vector of 10 million single character strings
## with 26 possible unique values
CommonSize <- 1e7
Common <- sample(LETTERS,CommonSize,replace = TRUE)
## Mix them into a data.table columns, "x0" through "x9"
DT_Original<- data.table(x0 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x1 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x2 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x3 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x4 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x5 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x6 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x7 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x8 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)),
x9 = as.factor(sample(c(Diverse,Common),size = CommonSize + DiverseSize, replace = FALSE)))
DT1 <- copy(DT_Original)
DT2 <- copy(DT_Original)
DT3 <- copy(DT_Original)
功能
unfactorize <- function(df){
for(i in which(sapply(df, class) == "factor")) df[[i]] = as.character(df[[i]])
return(df)
}
set_unfactorize <- function(df){
for(col in names(df)[which(sapply(df, class) == "factor")]) set(df, j = col, value = as.character(df[[col]]))
}
执行
然后,我使用 RStudio 的内置分析工具分析了以下三个语句。
## Original
DT1 <- unfactorize(DT1)
## data.table::set version
set_unfactorize(DT2)
## Outside of function
for(col in names(DT3)[which(sapply(DT3, class) == "factor")]) set(DT3, j = col, value = as.character(DT3[[col]]))
分析结果
我对结果感到非常惊讶——基本 R 版本似乎执行得最快并且使用的内存最少,尽管我预计它需要一个副本。这是对的,还是我在这里遗漏了什么?
解决方案
推荐阅读
- botframework - Microsoft Teams APP Studio - 在清单编辑器中找不到消息端点字段
- python - 如何使用 PuLP 编写迭代 LP 变量、obj 函数和约束?
- java - LibGDX 纹理在移动时闪烁 - 似乎没有什么可以解决它
- spring - 无法为某些 URL 禁用 Spring Security 过滤器链
- javascript - Typescript 模块 xyz 没有库 node_modules 的专家成员
- javascript - 以编程方式创建的 Vue 组件缺少在 Vue.prototype 上定义的全局属性
- javascript - 使用 Javascript .sort 函数对包含数字的字符串进行排序
- javascript - 如何在另一个 div jquery 上克隆一个 div
- flask - 在 Flask-SocketIO 房间中向客户端发送特定消息的问题
- flutter - 无法从包含 Firebase PhoneAutherisation 的未来提供商获取数据