根据其他数据框更改列 class
Change column class based on other data frame
我有一个数据框,我正在尝试根据 col_type 转换 dt 的每个变量的 class。
查找下面的示例以获取更多详细信息。
> dt
id <- c(1,2,3,4)
a <- c(1,4,5,6)
b <- as.character(c(0,1,1,4))
c <- as.character(c(0,1,1,0))
d <- c(0,1,1,0)
dt <- data.frame(id,a,b,c,d, stringsAsFactors = FALSE)
> str(dt)
'data.frame': 4 obs. of 5 variables:
$ id: num 1 2 3 4
$ a : num 1 4 5 6
$ b : chr "0" "1" "1" "4"
$ c : chr "0" "1" "1" "0"
$ d : num 0 1 1 0
现在,我正在尝试根据以下数据框转换每列的 class。
> var
var <- c("id","a","b","c","d")
type <- c("character","numeric","numeric","integer","character")
col_type <- data.frame(var,type, stringsAsFactors = FALSE)
> col_type
var type
1 id character
2 a numeric
3 b numeric
4 c integer
5 d character
我想将 id 转换为 class 在 col_type 数据框中的提及,对于所有其他列依此类推。
我的尝试:
setDT(dt)
for(i in 1:ncol(dt)){
if(colnames(dt)[i]%in%col_type$var){
a <- col_type[col_type$var==paste0(intersect(colnames(dt)[i],col_type$var)),]
dt[,col_type$var[i]:=eval(parse(text = paste0("as.",col_type$type[i],"(",col_type$var[i],")")))]
}
}
注意-我的解决方案有效,但它真的很慢,我想知道我是否可以更高效、更干净地完成它。
我们将不胜感激。
我会使用从 col_type
table:
派生的 colClasses
参数读取数据
library(data.table)
library(magrittr)
setDT(col_type)
res = capture.output(fwrite(dt)) %>% paste(collapse="\n") %>%
fread(colClasses = col_type[, setNames(type, var)])
str(res)
Classes ‘data.table’ and 'data.frame': 4 obs. of 5 variables:
$ id: chr "1" "2" "3" "4"
$ a : num 1 4 5 6
$ b : num 0 1 1 4
$ c : int 0 1 1 0
$ d : chr "0" "1" "1" "0"
- attr(*, ".internal.selfref")=<externalptr>
如果您可以在最初读入数据时执行此操作,则可以简化为...
res = fread("file.csv", colClasses = col_type[, setNames(type, var)])
无需 data.table 即可轻松完成所有这些操作。
如果数据永远不会以某种方式读入 R(接收为 RDS?),则有:
setDT(dt)
res = dt[, Map(as, .SD, col_type$type), .SDcols=col_type$var]
str(res)
Classes ‘data.table’ and 'data.frame': 4 obs. of 5 variables:
$ id: chr "1" "2" "3" "4"
$ a : num 1 4 5 6
$ b : num 0 1 1 4
$ c : int 0 1 1 0
$ d : chr "0" "1" "1" "0"
- attr(*, ".internal.selfref")=<externalptr>
考虑 Map
中的基 R 的 get()
,它可用于使用 as.*
函数从其字符串文字中检索函数。然后将向量列表绑定到数据框中。
vec_list <- Map(function(v, t) get(paste0("as.", t))(dt[[v]]), col_type$var, col_type$type)
dt_new <- data.frame(vec_list, stringsAsFactors = FALSE)
str(dt_new)
# 'data.frame': 4 obs. of 5 variables:
# $ id: chr "1" "2" "3" "4"
# $ a : num 1 4 5 6
# $ b : num 0 1 1 4
# $ c : int 0 1 1 0
# $ d : chr "0" "1" "1" "0"
如果转换可能会失败,可能将 get()
包装在 tryCatch
中。
我有一个数据框,我正在尝试根据 col_type 转换 dt 的每个变量的 class。 查找下面的示例以获取更多详细信息。
> dt
id <- c(1,2,3,4)
a <- c(1,4,5,6)
b <- as.character(c(0,1,1,4))
c <- as.character(c(0,1,1,0))
d <- c(0,1,1,0)
dt <- data.frame(id,a,b,c,d, stringsAsFactors = FALSE)
> str(dt)
'data.frame': 4 obs. of 5 variables:
$ id: num 1 2 3 4
$ a : num 1 4 5 6
$ b : chr "0" "1" "1" "4"
$ c : chr "0" "1" "1" "0"
$ d : num 0 1 1 0
现在,我正在尝试根据以下数据框转换每列的 class。
> var
var <- c("id","a","b","c","d")
type <- c("character","numeric","numeric","integer","character")
col_type <- data.frame(var,type, stringsAsFactors = FALSE)
> col_type
var type
1 id character
2 a numeric
3 b numeric
4 c integer
5 d character
我想将 id 转换为 class 在 col_type 数据框中的提及,对于所有其他列依此类推。
我的尝试:
setDT(dt)
for(i in 1:ncol(dt)){
if(colnames(dt)[i]%in%col_type$var){
a <- col_type[col_type$var==paste0(intersect(colnames(dt)[i],col_type$var)),]
dt[,col_type$var[i]:=eval(parse(text = paste0("as.",col_type$type[i],"(",col_type$var[i],")")))]
}
}
注意-我的解决方案有效,但它真的很慢,我想知道我是否可以更高效、更干净地完成它。
我们将不胜感激。
我会使用从 col_type
table:
colClasses
参数读取数据
library(data.table)
library(magrittr)
setDT(col_type)
res = capture.output(fwrite(dt)) %>% paste(collapse="\n") %>%
fread(colClasses = col_type[, setNames(type, var)])
str(res)
Classes ‘data.table’ and 'data.frame': 4 obs. of 5 variables:
$ id: chr "1" "2" "3" "4"
$ a : num 1 4 5 6
$ b : num 0 1 1 4
$ c : int 0 1 1 0
$ d : chr "0" "1" "1" "0"
- attr(*, ".internal.selfref")=<externalptr>
如果您可以在最初读入数据时执行此操作,则可以简化为...
res = fread("file.csv", colClasses = col_type[, setNames(type, var)])
无需 data.table 即可轻松完成所有这些操作。
如果数据永远不会以某种方式读入 R(接收为 RDS?),则有:
setDT(dt)
res = dt[, Map(as, .SD, col_type$type), .SDcols=col_type$var]
str(res)
Classes ‘data.table’ and 'data.frame': 4 obs. of 5 variables:
$ id: chr "1" "2" "3" "4"
$ a : num 1 4 5 6
$ b : num 0 1 1 4
$ c : int 0 1 1 0
$ d : chr "0" "1" "1" "0"
- attr(*, ".internal.selfref")=<externalptr>
考虑 Map
中的基 R 的 get()
,它可用于使用 as.*
函数从其字符串文字中检索函数。然后将向量列表绑定到数据框中。
vec_list <- Map(function(v, t) get(paste0("as.", t))(dt[[v]]), col_type$var, col_type$type)
dt_new <- data.frame(vec_list, stringsAsFactors = FALSE)
str(dt_new)
# 'data.frame': 4 obs. of 5 variables:
# $ id: chr "1" "2" "3" "4"
# $ a : num 1 4 5 6
# $ b : num 0 1 1 4
# $ c : int 0 1 1 0
# $ d : chr "0" "1" "1" "0"
如果转换可能会失败,可能将 get()
包装在 tryCatch
中。