【问题标题】:extract data based on datetime根据日期时间提取数据
【发布时间】:2017-05-20 21:19:04
【问题描述】:

我有两个数据框:

  • dat 是一个 9752x8 的数据帧,其中包含一些 POSIXlt 日期

  • trips.df 是一个 35772x28 数据帧,包含每小时温度
    数据

我想在dat中保存每个日期对应的温度。

我试过了:

trips.df$temperature<-lapply(trips.df$fin, function(x){
   dat_meteo[dat_meteo$Date.Heure==round(x,"hours"),7]})

但我得到了这个错误,这让我认为 x 没有作为日期时间变量传递

 Error in round(x, "hours") : 
  non-numeric argument to mathematical function

我也试过这个:

merge(trips.df,dat_meteo[,c(1,7)])

但我也遇到了错误:

Error: cannot allocate vector of size 653.8 Mb

关于如何按日期检索 dat_meteo 数据的任何建议?

我在 Windows 10 上使用 R 版本 3.4.0 和 RStudio 版本 1.0.143 以下是我的数据摘录:

> head(trips.df$fin)
[1] "2013-06-25 16:34:16 EDT" "2013-06-25 16:34:16 EDT" "2013-06-26 13:00:05 EDT"
[4] "2013-06-29 12:52:21 EDT" "2013-06-29 15:34:13 EDT" "2013-06-29 17:39:29 EDT"
> dat_meteo[1870:1875,c(1,7)]
              Date.Heure Temp...C.
1870 2013-03-19 18:00:00      -1,2
1871 2013-03-19 19:00:00      -1,7
1872 2013-03-19 20:00:00      -2,1
1873 2013-03-19 21:00:00      -2,8
1874 2013-03-19 22:00:00      -3,0
1875 2013-03-19 23:00:00      -3,7

【问题讨论】:

  • 确保两个时间列的格式相同,例如POSIXctround() 实际上似乎将POSIXct 转换为POSIXlt,所以你可以这样做as.POSIXct(round(trips.df$fin,"hours"))。然后你可以使用match()获取对应的索引或者merge,应该可以了。
  • @Lamia,感谢您的意见。代码会是什么样子?我试过这个没有运气:merge(trips.df,dat_meteo[1,7],by.x=as.POSIXct(round(trips.df$fin,"hours")),by.y = dat_meteo$Date.Heure)
  • by.xby.y 需要列名而不是列本身。在trips.df中添加另一列:trips.df$finhours=as.POSIXct(round(trips.df‌​$fin,"hours")),然后执行merge(trips.df,dat_meteo[,c(1,7)],by.x="finhours",by.y ="Date.Heure")
  • 您确定dat_meteo$Date.Heure 不是POSIXltPOSIXctPOSIXlt 是两种完全不同的格式。您应该在问题中包含 2 个数据框的 str()。
  • 这个问题很难回答,因为它缺少minimal reproducible example。下次请使用dput(x) 提供工作数据。使用dput(),您使用的数据类型会立即显而易见(比str() 好。您在问题中打印的数据摘录既不显示数据类型,也不适合构成一个工作示例(时间/日期范围不重叠)。谢谢。

标签: r datetime merge lapply


【解决方案1】:

您可能希望采用稍微不同的方法并使用data.table

trips.dt <- data.table(trips.df)
dat      <- data.table(dat)
trips.dt <- trips.dt[ , dates.a := strptime(as.POSIXct(fin,format='%m/%d/%Y %H:%M:%S'),format='%m/%d/%Y')][,dates.b := dates.a]
dat      <- dat[dates.dat.a := strptime(as.POSIXct(Date.Heure, format = '%m/%d/%Y %H:%M:%S'),format='%m/%d/%Y')][, dates.dat.b := dates.dat.a]
setkey(trips.dt, id, dates.a, dates.b)
setkey(dat , id, dates.dat.a, dates.dat.b)
combo    <- foverlaps(trips.df, dat, type = "within")

这会在将trip.dfdat 转换为data.table 后创建日期范围,然后将trips.df 合并到dat 并将结果存储为combo

【讨论】:

  • 谢谢!我不熟悉data.table。不过有一个问题,dates.adates.dat.a 代表什么?
  • 没什么。我或多或少只是不想覆盖原始变量。
【解决方案2】:

确保要匹配的两个时间列具有相同的格式 (POSIXct)。在数据框中使用POSIXct 格式更直接,因为POSIXlt 格式实际上对应于命名元素的列表,而POSIXct 是矢量形式。

dat_meteo$Date.Heure=as.POSIXct(dat_meteo$Date.Heure,format="%Y-%m-%d %H:%M:%S")

在trips.df 中创建一个四舍五入到最接近小时的时间列,也将其转换为POSIXct,因为round 将POSIXct 转换为POSIXlt

trips.df$fin_r=as.POSIXct(round(trips.df‌​$fin,"hours"))

然后使用merge:

res=merge(trips.df,dat_meteo[,c(1,7)],by.x="fin_r",by.y ="Date.Heure")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2020-07-31
    • 2020-03-02
    • 1970-01-01
    相关资源
    最近更新 更多