将数据框中的变量强制转换为适当的格式
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)
但是,由于存在多个问题,我认为这并不是正确的解决方案:
- 我怀疑有更快的方法来完成这个
- 出于某种原因,我收到了警告
In FUN(X[[i]], ...) : NAs introduced by coercion
,但事实并非如此(查看结果)
- 这在处理其他数据类型(即日期)时似乎不合适
是否有通用的启发式方法或其他更可持续的解决方案?谢谢
您应该检查 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::fread
或 readr
包在识别列并将其转换为适当类型方面做得相当不错。
所以我的第一反应是建议将数据写入文件,然后再读入,例如
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)
我正在处理一个由多种不同数据类型(数字、字符、时间戳)组成的数据框,但不幸的是,它们都是作为字符接收的。因此,我需要尽可能高效地动态地将它们强制转换为 "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)
但是,由于存在多个问题,我认为这并不是正确的解决方案:
- 我怀疑有更快的方法来完成这个
- 出于某种原因,我收到了警告
In FUN(X[[i]], ...) : NAs introduced by coercion
,但事实并非如此(查看结果) - 这在处理其他数据类型(即日期)时似乎不合适
是否有通用的启发式方法或其他更可持续的解决方案?谢谢
您应该检查 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::fread
或 readr
包在识别列并将其转换为适当类型方面做得相当不错。
所以我的第一反应是建议将数据写入文件,然后再读入,例如
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)