根据R中匹配列的模板更改数据框列的数据类型

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

我有2个数据帧.

  • 模板 - 我将使用此数据框中的数据类型.
  • df - 我想根据模板更改此数据框的数据类型.

我想首先根据第二个数据帧更改数据类型.让我们假设我有以下数据框架,我用作模板.

> template
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)
template <- data.frame(id,a,b,c,d, stringsAsFactors = FALSE)

> str(template)
'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)

我正在寻找下面的东西.

  • 在df中将模板的数据类型转换为完全相同.
  • 它应该具有模板框架中的相同列.

**注意 - 如果df中没有,则应添加所有NA的其他列.

> df
id <- c(6,7,12,14,1,3,4,4)
a <- c(0,1,13,1,3,4,5,6)
b <- c(1,4,12,3,4,5,6,7)
c <- c(0,0,13,3,4,45,6,7)
e <- c(0,0,13,3,4,45,6,7)
df <- data.frame(id,a,b,c,e)

> str(df)
'data.frame':   8 obs. of  5 variables:
 $ id: num  6 7 12 14 1 3 4 4
 $ a : num  0 1 13 1 3 4 5 6
 $ b : num  1 4 12 3 4 5 6 7
 $ c : num  0 0 13 3 4 45 6 7
 $ e : num  0 0 13 3 4 45 6 7
Run Code Online (Sandbox Code Playgroud)

期望的输出 -

> output
    id  a  b  c  d
    1  6  0  1  0 NA
    2  7  1  4  0 NA
    3 12 13 12 13 NA
    4 14  1  3  3 NA
    5  1  3  4  4 NA
    6  3  4  5 45 NA
    7  4  5  6  6 NA
    8  4  6  7  7 NA

> str(output)

'data.frame':   8 obs. of  5 variables:
 $ id: num  6 7 12 14 1 3 4 4
 $ a : num  0 1 13 1 3 4 5 6
 $ b : chr  "1" "4" "12" "3" ...
 $ c : chr  "0" "0" "13" "3" ...
 $ d : logi  NA NA NA NA NA NA ...
Run Code Online (Sandbox Code Playgroud)

我的尝试 -

template <- fread("template.csv"),header=TRUE,stringsAsFactors = FALSE)
n <- names(template)
template[,(n) :=  lapply(.SD,function(x) gsub("[^A-Za-z0-90 _/.-]","", as.character(x)))]
n <- names(df)
df[,(n) :=  lapply(.SD,function(x) gsub("[^A-Za-z0-90 _/.-]","", as.character(x)))]
output <- rbindlist(list(template,df),use.names = TRUE,fill = TRUE,idcol="template")
Run Code Online (Sandbox Code Playgroud)

在此之后,我编写输出数据帧,然后使用write.csv重新读取数据类型.但是,我搞砸了数据类型.请建议任何适当的方式来处理它.

Fra*_*ank 2

我会做

res = data.frame(
  lapply(setNames(,names(template)), function(x) 
    if (x %in% names(df)) as(df[[x]], class(template[[x]])) 
    else template[[x]][NA_integer_]
  ), stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

或与马格利特

library(magrittr)

setNames(, names(template)) %>% 
  lapply(. %>% {
    if (. %in% names(df)) as(df[[.]], class(template[[.]])) 
    else template[[.]][NA_integer_]
  }) %>% data.frame(stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

正在验证...

'data.frame':   8 obs. of  5 variables:
 $ id: num  6 7 12 14 1 3 4 4
 $ a : num  0 1 13 1 3 4 5 6
 $ b : chr  "1" "4" "12" "3" ...
 $ c : chr  "0" "0" "13" "3" ...
 $ d : num  NA NA NA NA NA NA NA NA
Run Code Online (Sandbox Code Playgroud)

如果您要做很​​多这样的事情,我建议您查看 vetr 包。它有一个很好的方法来处理数据框及其列的模板。