【问题标题】:Simultaneously merge multiple data frames with left join crashes RStudio同时合并多个数据框与左连接崩溃 RStudio
【发布时间】:2018-12-28 17:18:47
【问题描述】:

我想使用来自dplyr 库的left_join 合并三个大型数据框。数据框具有相同的结构,它们有 9859 个观测值和 4 个变量,只有第四个不同。最后,我需要的是一个包含六列(3 个共享变量和 3 个不同变量)的数据框。

我过去可以使用“tidyverse”和“dplyr”来做到这一点,但现在 RStudio 不断崩溃并冻结我的笔记本电脑。另外,我可以在前两个数据帧中使用left_join,但在加入第三个数据帧时不能。

我能够对多个数据框执行“left_join”,我认为这可能与我的数据有关,但我不知道是什么。可以下载三个数据框here的文件

sessionInfo()
R version 3.4.4 (2018-03-15)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

数据框似乎具有相同的结构

str(df.u)
'data.frame':   9859 obs. of  4 variables:
 $ event_id : num  3.51e+09 3.51e+09 3.51e+09 3.51e+09 3.51e+09 ...
 $ timestamp: POSIXct, format: "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" ...
 $ raster.id: chr  "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" ...
 $ u_wind   : num  -1.28 -1.3 -1.31 -1.32 -1.32 ...
str(df.v)
'data.frame':   9859 obs. of  4 variables:
 $ event_id : num  3.51e+09 3.51e+09 3.51e+09 3.51e+09 3.51e+09 ...
 $ timestamp: POSIXct, format: "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" ...
 $ raster.id: chr  "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" ...
 $ v_wind   : num  -1.52 -1.53 -1.53 -1.54 -1.54 ...
str(df.w)
'data.frame':   9859 obs. of  4 variables:
 $ event_id : num  3.51e+09 3.51e+09 3.51e+09 3.51e+09 3.51e+09 ...
 $ timestamp: POSIXct, format: "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" "2017-08-08 20:38:37" ...
 $ raster.id: chr  "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" "2017-08-08_20_40_10" ...
 $ w_wind   : num  -0.02343 -0.00834 0.00273 0.01357 0.01842 ...

这是我到目前为止尝试过的代码,哪些有效,哪些崩溃:

library(tidyverse)
# this craches 
dat.wind <- left_join(df.u, df.v, by=c('event_id', 'timestamp', 'raster.id')) %>% left_join(dat.wind, df.w, by=c('event_id', 'timestamp', 'raster.id'))

如果我分两步完成,第一个不会崩溃,但第二个会:

dat.wind <- left_join(df.u, df.v, by=c('event_id', 'timestamp', 'raster.id')) # doesn't crash
dat.wind2 <- left_join(dat.wind, df.v, by=c('event_id', 'timestamp', 'raster.id')) # crashes

我也尝试过转换成列表并使用 Paul Rougieux here 建议的解决方案

list(df.u, df.f, df.w) %>% reduce(left_join, by=c('event_id', 'timestamp', 'raster.id')) # also crahses

在这种特定情况下,我可以简单地使用数据框函数来获得所需的结果,但这是循环的一部分,可能会变得更复杂。

dat.wind <- data.frame('event_id' = df.u$event_id, 'timestamp' = df.u$timestamp, 'raster.id' = df.u$raster.id, 'u_wind' = df.u$u_wind, 'v_wind' = df.v$v_wind, 'w_wind' = df.w$w_wind)
# this is what I want
head(dat.wind)
    event_id           timestamp           raster.id    u_wind    v_wind       w_wind
1 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.277772 -1.520014 -0.023433736
2 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.295119 -1.526865 -0.008342839
3 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.305293 -1.531078  0.002726094
4 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.317489 -1.535781  0.013570182
5 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.324802 -1.538454  0.018419913
6 3512002602 2017-08-08 20:38:37 2017-08-08_20_40_10 -1.326861 -1.539239  0.019975858

【问题讨论】:

  • 所有 3 个数据帧中左侧连接中的 by 是相同的。这意味着将有 9859 行匹配 9859 行(基本上是 n^2)。由于内存问题,您可能会崩溃。
  • 感谢您的评论,现在很清楚 left_join 的工作原理了。

标签: r dplyr left-join rstudio tidyverse


【解决方案1】:

为了扩展Jake's comment,这并不是left_join 的真正用例,因为每一行没有不同的ID 列。如果您尝试进行此匹配,将会发生的情况是第一个数据帧中的每一行将与其他 9859 行匹配,然后 97,199,881 行中的每一行将尝试与第三次匹配中的 9859 匹配。相反,如果您想继续使用管道,您可以使用 bind_colsmutate 来复制列。或者,如果你真的想使用left_join,你可以在每个数据框中添加一个row id 列,使每一行不同,然后将其删除:

当然,如果不希望前三列只有一个不同的值,那么请检查您的数据源!

df.u %>%
  bind_cols(df.v['v_wind'], df.w['w_wind'])
df.u %>%
  mutate(v_wind = df.v$v_wind, w_wind = df.w$w_wind)
df.u %>%
  rowid_to_column() %>%
  left_join(rowid_to_column(df.v), by = c('rowid', 'event_id', 'timestamp', 'raster.id')) %>%
  left_join(rowid_to_column(df.w), by = c('rowid', 'event_id', 'timestamp', 'raster.id')) %>%
  select(-rowid)

【讨论】:

  • 我可以看到使用bind_cols 更适合我的目的。感谢您指出这一点!
【解决方案2】:

你可以试试:

jdfs

【讨论】:

  • 为什么你的by声明是空的?
  • mystake, by = "dataframes 之间公共变量的名称"
猜你喜欢
  • 2018-03-18
  • 2023-02-10
  • 2018-04-08
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多