将数据框中的变量强制转换为适当的格式

Coerce variables in data frame to appropriate format

我正在处理一个由多种不同数据类型(数字、字符、时间戳)组成的数据框,但不幸的是,它们都是作为字符接收的。因此,我需要尽可能高效地动态地将它们强制转换为 "appropriate" 格式。

考虑以下示例:

df <- data.frame("val1" = c("1","2","3","4"), "val2" = c("A", "B", "C", "D"), stringsAsFactors = FALSE)

我显然希望 val1 是数字,而 val2 保留为字符。因此,我的结果应该是这样的:

'data.frame':   4 obs. of  2 variables:
 $ val1: num  1 2 3 4
 $ val2: chr  "A" "B" "C" "D"

现在,我正在通过检查强制转换是否会导致 NULL 来完成此操作,如果不是这种情况,则继续强制转换:

res <- as.data.frame(lapply(df, function(x){

  x <- sapply(x, function(y) {
    if (is.na(as.numeric(y))) {
      return(y)
    } else {
      y <- as.numeric(y)
      return(y)
    }    
  })

  return(x)

}), stringsAsFactors = FALSE) 

但是,由于存在多个问题,我认为这并不是正确的解决方案:

  1. 我怀疑有更快的方法来完成这个
  2. 出于某种原因,我收到了警告 In FUN(X[[i]], ...) : NAs introduced by coercion,但事实并非如此(查看结果)
  3. 这在处理其他数据类型(即日期)时似乎不合适

是否有通用的启发式方法或其他更可持续的解决方案?谢谢

您应该检查 dataPreparation 包。您会发现 function findAndTransformNumerics function 可以完全满足您的需求。

require(dataPreparation)
data("messy_adult")
sapply(messy_adult[, .(num1, num2, mail)], class)
   num1        num2        mail 
"character" "character"    "factor" 

messy_adult 是一个丑陋的数据集,用来说明这个包的功能。这里 num1 和 num2 是字符串:/

messy_adult <- findAndTransformNumerics(messy_adult)
[1] "findAndTransformNumerics: It took me 0.18s to identify 3 numerics column(s), i will set them as numerics"
[1] "setColAsNumeric: I will set some columns as numeric"
[1] "setColAsNumeric: I am doing the columnnum1"
[1] "setColAsNumeric: 0 NA have been created due to transformation to numeric."
[1] "setColAsNumeric: I will set some columns as numeric"
[1] "setColAsNumeric: I am doing the columnnum2"
[1] "setColAsNumeric: 0 NA have been created due to transformation to numeric."
[1] "setColAsNumeric: I am doing the columnnum3"
[1] "setColAsNumeric: 0 NA have been created due to transformation to numeric."
[1] "findAndTransformNumerics: It took me 0.09s to transform 3 column(s) to a numeric format."

这里我们执行了搜索,它记录了找到的内容

并且知道:

sapply(messy_adult[, .(num1, num2, mail)], class)
     num1      num2      mail 
"numeric" "numeric"  "factor" 

希望对您有所帮助!

免责声明:我是这个包的作者。

最近的文件阅读器,如 data.table::freadreadr 包在识别列并将其转换为适当类型方面做得相当不错。

所以我的第一反应是建议将数据写入文件,然后再读入,例如

library(data.table)
fwrite(df, "dummy.csv")
df_new <- fread("dummy.csv")
str(df_new)
Classes ‘data.table’ and 'data.frame':    4 obs. of  2 variables:
 $ val1: int  1 2 3 4
 $ val2: chr  "A" "B" "C" "D"
 - attr(*, ".internal.selfref")=<externalptr>

或不实际写入磁盘:

df_new <- fread(paste(capture.output(fwrite(df, "")), collapse = "\n"))

然而, 更聪明,但需要一些改进以避免强制转换为因子:

df[] <- lapply(df, type.convert, as.is = TRUE)
str(df)
'data.frame': 4 obs. of  2 variables:
 $ val1: int  1 2 3 4
 $ val2: chr  "A" "B" "C" "D"

df[] <- lapply(df, readr::parse_guess)