【问题标题】:bind_rows of different data types不同数据类型的bind_rows
【发布时间】:2016-09-07 19:02:43
【问题描述】:

我想堆叠一个 data.frames 列表,但有时这些列具有不同的数据类型。我希望操作强制到最低公分母(在我的情况下通常是 character)。

这种堆叠发生在package function 内,该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) 数据库中的元数据来影响强制转换的长期计划,但我希望有一个短期通用解决方案用于堆叠操作。

【问题讨论】:

  • 它也适用于rbind。我假设您希望将批处理的 API 调用绑定在一起,因此它们都应该具有相同的名称。
  • 在这种情况下,我通常将它们转换为因子,但我不确定如果将每一列转换为因子列然后将它们转换回来,它会在多大程度上影响速度..
  • fwiw,在 ds_a 充满整数而 ds_b 是字符的情况下,我会执行 ds_5&lt;-bind_rows(ds_a%&gt;%mutate_all(as.character),ds_b) 之类的操作。

标签: r dplyr redcap


【解决方案1】:

我们可以从data.table使用rbindlist

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.table - 从(并可能返回)tibble 的转换中是否有任何损失?
  • @geryan 据我所知。当您转换为tibble 时,会添加一些属性并删除一些其他属性
【解决方案2】:

最近我切换到一种方法,最初将所有列保留为字符串(从纯文本转换为 data.frame 时),然后堆叠,最后将 converts the columns 转换为适当的数据类型,之后它具有所有行做出决定(使用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 月 3 日创建

【讨论】:

  • 这对我不起作用,授予的版本可能会随着时间而改变
  • @obewanjacobi,错误信息是什么?今天它在两个带有更新包的操作系统上为我工作。你贴的准确吗?
  • 今天再次运行它,这次工作,虽然我会说我尝试了 2 组不同的数据,但它没有工作。不过,在上面运行您的代码确实会发出一些奇怪的警告:Warning message: ... is not empty. We detected these problematic arguments: * needs_dots These dots only exist to allow future extensions and should be empty. Did you misspecify an argument?
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 2020-05-08
  • 2017-08-29
  • 2011-05-10
  • 2019-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多