bind_rows 种不同的数据类型
bind_rows of different data types
我想堆叠一个 data.frames 的列表,但有时这些列具有不同的数据类型。我希望该操作强制转换为最低公分母(在我的情况下通常是 character
)。
这种堆叠发生在 package function 中,它几乎可以接受任何 data.frames 的列表。它实际上没有能力将 ds_a$x
强制转换为 bind_rows()
.
之前的字符
ds_a <- data.frame(
x = 1:6,
stringsAsFactors = FALSE
)
ds_b <- data.frame(
x = c("z1", "z2"),
stringsAsFactors = FALSE
)
# These four implementations throw:
# Error: Can not automatically convert from integer to character in column "x".
ds_1 <- dplyr::bind_rows(ds_a, ds_b)
ds_2 <- dplyr::bind_rows(ds_b, ds_a)
ds_3 <- dplyr::bind_rows(list(ds_a, ds_b))
ds_4 <- dplyr::union_all(ds_a, ds_b)
我希望输出 data.frame 具有单个字符向量:
x
1 1
2 2
3 3
4 4
5 5
6 6
7 z1
8 z2
我有一些使用 (REDCap) 数据库中的元数据来影响强制转换的长期计划,但我希望有一个针对堆叠操作的短期通用解决方案。
我们可以使用 rbindlist
来自 data.table
library(data.table)
rbindlist(list(ds_a, ds_b))
# x
#1: 1
#2: 2
#3: 3
#4: 4
#5: 5
#6: 6
#7: z1
#8: z2
最近我切换到一种方法,最初将所有列保留为字符串(从纯文本转换为 data.frame),然后是堆栈,最后是 converts the columns to an appropriate data type after it has all the rows to make a decision (using readr::type_convert()
)。
模仿这个例子。我没有做过任何性能比较,但没有明显的区别(互联网是真正的瓶颈)。另外,我有点喜欢减少数据类型转换次数的想法。
library(magrittr)
col_types <- readr::cols(.default = readr::col_character())
raw_a <- "x,y\n1,21\n2,22\n3,23\n4,24\n5,25\n6,26"
raw_b <- "x,y\nz1,31\nz2,32"
ds_a <- readr::read_csv(raw_a, col_types=col_types)
ds_b <- readr::read_csv(raw_b, col_types=col_types)
list(ds_a, ds_b) %>%
dplyr::bind_rows() %>%
readr::type_convert()
#> Parsed with column specification:
#> cols(
#> x = col_character(),
#> y = col_double()
#> )
#> # A tibble: 8 x 2
#> x y
#> <chr> <dbl>
#> 1 1 21
#> 2 2 22
#> 3 3 23
#> 4 4 24
#> 5 5 25
#> 6 6 26
#> 7 z1 31
#> 8 z2 32
由 reprex package (v0.3.0)
于 2019-12-03 创建
我想堆叠一个 data.frames 的列表,但有时这些列具有不同的数据类型。我希望该操作强制转换为最低公分母(在我的情况下通常是 character
)。
这种堆叠发生在 package function 中,它几乎可以接受任何 data.frames 的列表。它实际上没有能力将 ds_a$x
强制转换为 bind_rows()
.
ds_a <- data.frame(
x = 1:6,
stringsAsFactors = FALSE
)
ds_b <- data.frame(
x = c("z1", "z2"),
stringsAsFactors = FALSE
)
# These four implementations throw:
# Error: Can not automatically convert from integer to character in column "x".
ds_1 <- dplyr::bind_rows(ds_a, ds_b)
ds_2 <- dplyr::bind_rows(ds_b, ds_a)
ds_3 <- dplyr::bind_rows(list(ds_a, ds_b))
ds_4 <- dplyr::union_all(ds_a, ds_b)
我希望输出 data.frame 具有单个字符向量:
x
1 1
2 2
3 3
4 4
5 5
6 6
7 z1
8 z2
我有一些使用 (REDCap) 数据库中的元数据来影响强制转换的长期计划,但我希望有一个针对堆叠操作的短期通用解决方案。
我们可以使用 rbindlist
来自 data.table
library(data.table)
rbindlist(list(ds_a, ds_b))
# x
#1: 1
#2: 2
#3: 3
#4: 4
#5: 5
#6: 6
#7: z1
#8: z2
最近我切换到一种方法,最初将所有列保留为字符串(从纯文本转换为 data.frame),然后是堆栈,最后是 converts the columns to an appropriate data type after it has all the rows to make a decision (using readr::type_convert()
)。
模仿这个例子。我没有做过任何性能比较,但没有明显的区别(互联网是真正的瓶颈)。另外,我有点喜欢减少数据类型转换次数的想法。
library(magrittr)
col_types <- readr::cols(.default = readr::col_character())
raw_a <- "x,y\n1,21\n2,22\n3,23\n4,24\n5,25\n6,26"
raw_b <- "x,y\nz1,31\nz2,32"
ds_a <- readr::read_csv(raw_a, col_types=col_types)
ds_b <- readr::read_csv(raw_b, col_types=col_types)
list(ds_a, ds_b) %>%
dplyr::bind_rows() %>%
readr::type_convert()
#> Parsed with column specification:
#> cols(
#> x = col_character(),
#> y = col_double()
#> )
#> # A tibble: 8 x 2
#> x y
#> <chr> <dbl>
#> 1 1 21
#> 2 2 22
#> 3 3 23
#> 4 4 24
#> 5 5 25
#> 6 6 26
#> 7 z1 31
#> 8 z2 32
由 reprex package (v0.3.0)
于 2019-12-03 创建