根据其他数据框更改列类

Rus*_*tel 5 r plyr dataframe dplyr data.table

我有一个数据框,我试图根据 col_type 转换 dt 每个变量的类。

查找下面的示例以了解更多详细信息。

> 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
Run Code Online (Sandbox Code Playgroud)

现在,我尝试根据下面的数据框转换每列的类。

> 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
Run Code Online (Sandbox Code Playgroud)

我想将 id 转换为 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],")")))]
  }
  
}
Run Code Online (Sandbox Code Playgroud)

注意-我的解决方案有效,但速度非常慢,我想知道是否可以更有效、更干净地完成它。

建议将不胜感激。

Fra*_*ank 2

colClasses我将使用从表中派生的参数读取数据col_type

\n
library(data.table)\nlibrary(magrittr)\nsetDT(col_type)\n\nres = capture.output(fwrite(dt)) %>% paste(collapse="\\n") %>% \n  fread(colClasses = col_type[, setNames(type, var)])\n\nstr(res)\nClasses \xe2\x80\x98data.table\xe2\x80\x99 and 'data.frame':  4 obs. of  5 variables:\n $ id: chr  "1" "2" "3" "4"\n $ a : num  1 4 5 6\n $ b : num  0 1 1 4\n $ c : int  0 1 1 0\n $ d : chr  "0" "1" "1" "0"\n - attr(*, ".internal.selfref")=<externalptr> \n
Run Code Online (Sandbox Code Playgroud)\n

如果您可以在最初读入数据时执行此操作,则可以简化为...

\n
 res = fread("file.csv", colClasses = col_type[, setNames(type, var)])\n
Run Code Online (Sandbox Code Playgroud)\n

无需 data.table 即可轻松完成所有这些操作。

\n
\n

如果不知何故数据从未读入 R(作为 RDS 接收?),则会出现:

\n
setDT(dt)\nres = dt[, Map(as, .SD, col_type$type), .SDcols=col_type$var]\n\nstr(res)\nClasses \xe2\x80\x98data.table\xe2\x80\x99 and 'data.frame':  4 obs. of  5 variables:\n $ id: chr  "1" "2" "3" "4"\n $ a : num  1 4 5 6\n $ b : num  0 1 1 4\n $ c : int  0 1 1 0\n $ d : chr  "0" "1" "1" "0"\n - attr(*, ".internal.selfref")=<externalptr> \n
Run Code Online (Sandbox Code Playgroud)\n

看看showMethods("coerce") 有些转换可能会失败,例如:as(letters[1:3], "factor")

\n