【问题标题】:R with Jupyter Notebook: Inner join two data frames on Date using dplyrR 与 Jupyter Notebook:使用 dplyr 在 Date 上内连接两个数据帧
【发布时间】:2018-05-01 20:43:15
【问题描述】:

我将 R 与 Jupyter Notebook 一起使用。我在这里的两个文件中使用 dplyr 创建了两个数据框:CSV files 为了准备数据,我从“自行车”文件中删除了列,并将日期字符串格式化为日期时间。

# drop colums that contain only one value
bikes <- select(bikes,-c(contract_name, bonus,banking))
# convert UNIX timestamp to a date-time
bikes$last_update <- bikes$last_update/1000
bikes$last_update <- as.POSIXct(bikes$last_update, origin="1970-01-01")

我使用 lubridate 库将读入的“Santander_Weather_F”转换为“weath”以转换日期。

weath$Date <- parse_date_time(weath$Date, "mdy")

这是我创建新数据框的方式:

avg_bikes_d <- bikes %>% select(last_update,available_bikes) %>% group_by(Date=lubridate::round_date(last_update,unit="day")) %>%
    summarise(avg_bikes=round(mean(available_bikes),0))
avg_weath <- weath %>% select(Date, temp_avg, wind_avg)

第一个数据框的数字列包含值 1 到 14。这意味着日期可以重复。生成的数据帧的头部如下所示:

| number | Date       | avg_bikes |
|--------|------------|-----------|
| 1      | 2017-05-30 | 0         |
| 1      | 2017-05-31 | 0         |
| 1      | 2017-06-01 | 2         |
| 1      | 2017-06-06 | 8         |
| 1      | 2017-06-07 | 17        |
| 1      | 2017-06-08 | 31        |

| Date       | temp_avg | wind_avg |
|------------|----------|----------|
| 2017-05-29 | 65       | 3        |
| 2017-05-30 | 64       | 3        |
| 2017-05-31 | 63       | 5        |
| 2017-06-01 | 66       | 3        |
| 2017-06-02 | 62       | 6        |
| 2017-06-03 | 61       | 5        |

我希望按日期进行内部连接: avg &lt;- inner_join(avg_bikes_d, avg_weath, by="Date") 但所有这些结果都是一个空的数据框。 我尝试删除第一个数据框的数字列作为检查,但仍然没有。我使用is.POSIXct() 检查了日期列的格式是否正确我还搜索了 dplyr 文档和其他帖子。我可能做错了什么?

【问题讨论】:

  • 嗯,看来你做得很好......你能分享dput()重现这个问题的最少数据吗?
  • 我编辑了问题以包含数据和我的数据清理过程。我怀疑我的问题在于我如何重新格式化日期或日期的读取方式。

标签: r datetime dplyr inner-join jupyter-notebook


【解决方案1】:

感谢您提供有关数据的详细信息。

这是因为时区不同。

avg_weath$Date[2]
#> [1] "2017-05-30 UTC"

# "JST" is my default timezone, so you probably get a different result.
avg_bikes_d$Date[1]
#> [1] "2017-05-30 JST"

参考https://github.com/tidyverse/dplyr/issues/3059

第一个是解析数字的结果没有时间戳,所以它们是模棱两可的。你知道这两个时间戳代表不同的时间点:

  • 2017-05-30 00:00:00 UTC
  • 2017-05-30 00:00:00 JST

但是,无论如何,我们无法确定053017 实际代表的数字是哪一位。这里,parse_date_time() 假定时区为 UTC(如果未提供 tz 参数)。

第二个来自纪元秒。这与时区无关,因此我们可以唯一确定时间戳。

bikes$last_update <- as.POSIXct(bikes$last_update, origin="1970-01-01")

处理时区是一项艰巨的工作。一种解决方案是force_tz()

avg_bikes_d$Date <- force_tz(avg_bikes_d$Date, "UTC")

但我猜你真正需要的是日期,而不是时间戳。那么,如何将Date 列转换为Date 类而不是POSIXct

weath$Date <- date(parse_date_time(weath$Date, "mdy"))

avg_bikes_d <- bikes %>%
  select(last_update,available_bikes) %>%
  group_by(Date=date(last_update)) %>%
  summarise(avg_bikes=round(mean(available_bikes),0))

【讨论】:

  • @lisa-de-castro 我已经更新了我的答案。这有意义吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
相关资源
最近更新 更多