r - 在绑定之前自动将一个数据框的所有列类型强制转换为另一个数据框的类型
问题描述
假设我有两个要绑定的数据框:
ds_a <- data.frame(
x = 1:6,
y = 5,
z = "4",
l = 2,
stringsAsFactors = FALSE
)
ds_b <- data.frame(
x = as.factor(1:6),
y = "5",
p = 2,
stringsAsFactors = FALSE
)
当我尝试绑定它们时,出现以下错误:
> bind_rows(ds_a, ds_b)
Error: Can't combine `..1$x` <integer> and `..2$x` <factor<4c79c>>.
通常我解决这个问题的方法是将两个数据帧中的所有列都转换为一个字符,绑定两个数据帧,然后手动将所有列重新转换回它们的原始类型。
有没有办法通过自动强制转换' 列以匹配(假设它们的名称相同)来简单地强制之间ds_a
的所有类型冲突?ds_b
ds_b
ds_a
更一般地说,我想要一个解决方案来自动将所有列转换为列名匹配ds_b
的任何位置的类型。ds_a
如果ds_b
并且ds_a
不共享所有相同的列,则该解决方案应该可以工作(当列不存在于另一个列时,只需填充 NA ,但在另一个列中存在)。
这是预期的结果:
ds_merged =read.table(text = 'x y z l p
1 1 5 4 2 NA
2 2 5 4 2 NA
3 3 5 4 2 NA
4 4 5 4 2 NA
5 5 5 4 2 NA
6 6 5 4 2 NA
7 1 5 NA NA 2
8 2 5 NA NA 2
9 3 5 NA NA 2
10 4 5 NA NA 2
11 5 5 NA NA 2
12 6 5 NA NA 2', header = TRUE, row.names = NULL)
> ds_merged
row.names x y z l p
1 1 1 5 4 2 NA
2 2 2 5 4 2 NA
3 3 3 5 4 2 NA
4 4 4 5 4 2 NA
5 5 5 5 4 2 NA
6 6 6 5 4 2 NA
7 7 1 5 NA NA 2
8 8 2 5 NA NA 2
9 9 3 5 NA NA 2
10 10 4 5 NA NA 2
11 11 5 5 NA NA 2
12 12 6 5 NA NA 2
解决方案
我们可以使用type.convert()
说明:OP评论后:
type_convert
不考虑ds_a
(您可以检查是否glimpse(ds_a)
与glimpse
结果数据框进行比较:
请注意 的列ds_a
具有与 中相同的类result
。
> # compare classes
> glimpse(ds_a)
Rows: 6
Columns: 4
$ x <int> 1, 2, 3, 4, 5, 6
$ y <dbl> 5, 5, 5, 5, 5, 5
$ z <chr> "4", "4", "4", "4", "4", "4"
$ l <dbl> 2, 2, 2, 2, 2, 2
> glimpse(ds_b)
Rows: 6
Columns: 3
$ x <fct> 1, 2, 3, 4, 5, 6
$ y <chr> "5", "5", "5", "5", "5", "5"
$ p <dbl> 2, 2, 2, 2, 2, 2
> glimpse(result)
Rows: 12
Columns: 5
$ x <int> 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6
$ y <dbl> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
$ z <chr> "4", "4", "4", "4", "4", "4", NA, NA, NA, NA, NA, NA
$ l <dbl> 2, 2, 2, 2, 2, 2, NA, NA, NA, NA, NA, NA
$ p <int> NA, NA, NA, NA, NA, NA, 2, 2, 2, 2, 2, 2
什么type.convert
是:
- 将最佳拟合类应用于
ds_b
(注意 %>% 在 内bind_rows
)的数据。所以所有ds_b$x
都是整数,因此 R 将类因子转换为 ds_b$x 中的类整数。 - 所有这些
ds_b$y
都是字符类,但本质上是整数,因此 R 将字符类转换为整数类。这可能会导致误解。但是,现在我们有ds_a$y
双类和ds_b$y
整数类 -> 但这对 R 来说没问题,bind_rows
这里双类覆盖整数。
> # showing what type.convert does to ds_b
> ds_b$x <- as.integer(ds_b$x)
> ds_b$y <- as.integer(ds_b$y)
> ds_b %>%
+ as_tibble()
# A tibble: 6 x 3
x y p
<int> <int> <dbl>
1 1 5 2
2 2 5 2
3 3 5 2
4 4 5 2
5 5 5 2
6 6 5 2
> ds_b %>%
+ as_tibble()
# A tibble: 6 x 3
x y p
<int> <int> <dbl>
1 1 5 2
2 2 5 2
3 3 5 2
4 4 5 2
5 5 5 2
6 6 5 2
> bind_rows(ds_a, ds_b) %>%
+ as_tibble()
# A tibble: 12 x 5
x y z l p
<int> <dbl> <chr> <dbl> <dbl>
1 1 5 4 2 NA
2 2 5 4 2 NA
3 3 5 4 2 NA
4 4 5 4 2 NA
5 5 5 4 2 NA
6 6 5 4 2 NA
7 1 5 NA NA 2
8 2 5 NA NA 2
9 3 5 NA NA 2
10 4 5 NA NA 2
11 5 5 NA NA 2
12 6 5 NA NA 2
- 将双精度类转换
ds_b$p
为整数类,因为数据本质上是整数。
解决方案:
library(dplyr)
bind_rows(ds_a, ds_b %>% type.convert(as.is=TRUE))
输出:
x y z l p
1 1 5 4 2 NA
2 2 5 4 2 NA
3 3 5 4 2 NA
4 4 5 4 2 NA
5 5 5 4 2 NA
6 6 5 4 2 NA
7 1 5 <NA> NA 2
8 2 5 <NA> NA 2
9 3 5 <NA> NA 2
10 4 5 <NA> NA 2
11 5 5 <NA> NA 2
12 6 5 <NA> NA 2
推荐阅读
- c# - 使用 AesManaged ECB 或 CBC 的加密/解密不适用于 .bin 文件
- javascript - Vue 获取发布数据到控制器 asp.net mvc
- c# - RX - 按订阅复杂性划分的多消费者
- angularjs - 允许用户只编辑他自己的文章
- swagger-2.0 - 如何使用 OpenApi Generator 为 java 生成一些模型?
- javascript - Linkedin 返回未捕获的错误:JavaScript API 域仅限于
- r - 一次为数据框中的多列生成线性模型
- jquery - 如果所选日期在 Js 日历中有特定日期,则将所选日期更改为明天
- c# - 为集成测试创建 LocalDB 测试数据库
- sql - 从 Oracle 数据库中的两个表中查询