【问题标题】:Loop between posixlt in RR中posixlt之间的循环
【发布时间】:2019-06-03 06:55:09
【问题描述】:

我在尝试循环时遇到 R 中的错​​误。这是我的数据框的一个子集(包含 120000 行)。

                 time value      mean group
1 2017-01-01 12:00:00 0.507 0.5106533    NA
2 2017-01-01 12:05:00 0.526 0.5106533    NA
3 2017-01-01 12:10:00 0.489 0.5106533    NA
4 2017-01-01 12:15:00 0.598 0.5106533    NA
5 2017-01-01 12:20:00 0.564 0.5106533    NA
6 2017-01-01 12:25:00 0.536 0.5106533    NA

假设我想根据时间段创建组,预期结果如下:

                 time value      mean group
1 2017-01-01 12:00:00 0.507 0.5106533    A
2 2017-01-01 12:05:00 0.526 0.5106533    A
3 2017-01-01 12:10:00 0.489 0.5106533    B
4 2017-01-01 12:15:00 0.598 0.5106533    B
5 2017-01-01 12:20:00 0.564 0.5106533    C
6 2017-01-01 12:25:00 0.536 0.5106533    C

我尝试了以下代码:

for (i in 1:length(merged.data$group)){
  if (merged.data[as.POSIXlt(i)$time >= "2017-05-15 12:00:00 GMT" & 
as.POSIXlt(i)$time <= "2017-05-29 12:00:00 GMT",]){
   merged.data$group == "A"} 
  else if (merged.data[as.POSIXlt(i)$time >= "2017-08-11 12:00:00" & 
as.POSIXlt(i)$time <= "2017-11-29 16:00:00",]){
    merged.data$group == "B"}
  else if (merged.data[as.POSIXlt(i)$time >= "2018-01-05 12:00:00" & 
as.POSIXlt(i)$time <= "2018-02-16 16:00:00",]){
    merged.data$group == "C"}
}

我收到以下错误:

Error in as.POSIXlt.numeric(i) : 'origin' must be supplied

我不明白,我认为 POSIXlt 正在摆脱起源问题?虽然,我承认我对 R 中时间问题的理解有点混乱,每次我需要处理时间/日期时,我都很难编码......

所以我希望有人可以帮助我,如果我不清楚或者是否需要更多/更好的信息来回答我的问题,请随时告诉我。

提前感谢stackoverflowers!

【问题讨论】:

  • 您的团体有哪些条件?这个as.POSIXlt(i)$time 也不是有效的 R 代码。此外,for i in 1:length(..) 所以你的i 是整数,你正试图将它转换为时间......你可能是指as.POSIXlt$time[i]as.POSIXct() 是矢量化的。另外,即使将其转换为时间,您也是在将其与字符("2017-05-15 12:00:00 GMT")进行比较...
  • as.POSIXlt(i) 失败,因为i 只是一个整数,因为您从1:length(merged.data$group) 循环。如果你要打电话给as.POSIXlt(i),那么你需要确保i是一个日期。
  • 我要创建的组包含在日期之间。感谢您的回答 Sotos,您明确表示我对那些日期/时间问题感到困惑!正如 shwan (thx btw) 所建议的那样,我将尝试更改我的代码并将 i 作为日期。我会在我的问题中更正它,但仍然对建议感兴趣。

标签: r loops time posixlt


【解决方案1】:

data.table 方法...

样本数据

library( data.table )

dt <- fread("time value mean 
2017-01-01T12:00:00 0.507 0.5106533    
2017-01-01T12:05:00 0.526 0.5106533    
2017-01-01T12:10:00 0.489 0.5106533   
2017-01-01T12:15:00 0.598 0.5106533    
2017-01-01T12:20:00 0.564 0.5106533    
2017-01-01T12:25:00 0.536 0.5106533    ", header = TRUE)

dt[, time := as.POSIXct( time, format = "%Y-%m-%dT%H:%M:%S" )]

代码

library( data.table )
library( lubridate )

dt[, group := LETTERS[.GRP], by = lubridate::floor_date( time, "10 mins" ) ]

#             time value      mean group
# 1: 2017-01-01 12:00:00 0.507 0.5106533     A
# 2: 2017-01-01 12:05:00 0.526 0.5106533     A
# 3: 2017-01-01 12:10:00 0.489 0.5106533     B
# 4: 2017-01-01 12:15:00 0.598 0.5106533     B
# 5: 2017-01-01 12:20:00 0.564 0.5106533     C
# 6: 2017-01-01 12:25:00 0.536 0.5106533     C

更新

使用foverlaps 的方法,基于提供的示例数据和代码

library( data.table )

#create lookup-table with periods and group-names  
periods.dt <- data.table( 
  start = as.POSIXct( c( "2017-05-15 12:00:00", "2017-08-11 12:00:00", "2018-01-05 12:00:00" ), tz = "GMT" ),
  stop = as.POSIXct( c( "2017-08-11 12:00:00", "2018-01-05 12:00:00", "2018-02-16 16:00:00"), tz = "GMT" ),
  group = LETTERS[1:3] )
#set keys
setkey( periods.dt, start, stop ) 

#create sample data
dt <- fread("time value mean 
            2017-01-01T12:00:00 0.507 0.5106533    
            2017-01-01T12:05:00 0.526 0.5106533    
            2017-01-01T12:10:00 0.489 0.5106533   
            2017-01-01T12:15:00 0.598 0.5106533    
            2017-01-01T12:20:00 0.564 0.5106533    
            2017-01-01T12:25:00 0.536 0.5106533    ", header = TRUE)

dt[, time := as.POSIXct( time, format = "%Y-%m-%dT%H:%M:%S", tz = "GMT" )]

#create dummies to join on
dt[, `:=`( start = time, stop = time )]

#perform overlap join, no match --> NA
foverlaps( dt, periods.dt, type = "within", nomatch = NA)[, c("time", "value","mean","group"), with = FALSE]
#                   time value      mean group
# 1: 2017-01-01 12:00:00 0.507 0.5106533  <NA>
# 2: 2017-01-01 12:05:00 0.526 0.5106533  <NA>
# 3: 2017-01-01 12:10:00 0.489 0.5106533  <NA>
# 4: 2017-01-01 12:15:00 0.598 0.5106533  <NA>
# 5: 2017-01-01 12:20:00 0.564 0.5106533  <NA>
# 6: 2017-01-01 12:25:00 0.536 0.5106533  <NA>

【讨论】:

  • 非常感谢,这真的很好,但不完全符合我想要的,但也许我的例子不够清楚。我的数据框相对较大(12000 行),我需要用日期而不是时间段来确定我的组,因为它对应于探测器的特定开始/停止测量。我更清楚了吗? (抱歉总是很难简单地解释你在做什么奇怪的事情^^)。
  • @DocMartin's 不,我不清楚你是如何定义你的组的......如果组在一个单独的表中,data.table::foverlaps() 可能是要走的路。您问题的 for 循环中的日期都超出了您的示例数据。
  • 感谢您的快速回答和编码。我花了一些时间,但我理解了代码,它对您的示例数据很有吸引力。我自己的数据确实有问题,当我尝试将我的 df 转换为 data.table 时收到以下消息:dimnames(x)
  • @DocMartin 很难说没有你的生产数据的样本数据......也许就你的问题提出一个关于 SO 的新问题是击球手。确保使用 dput() 包含样本数据,所以我们知道你在做什么..
  • 我再次感谢您 Wimpel,现在没关系,我明白出了什么问题,可以使用您的完美解决方案!亲切的问候,
【解决方案2】:

感谢您的回答,我发现只有日期对我有用,因为我的数据集中存在巨大差距。通过一个简单的 ifelse,我发现了一些有用的东西:

merged.data$group= "2017-05-15" & merge.data$date = "2017-08-11" & merge.data$date = "2018-01-05" & merge.data$date

这不适用于我拥有的 POSIXlt 对象,但 Wimpel 提供的解决方案似乎有效(我在使用 data.table 时遇到问题,但那是另一回事!)

再次感谢,这个论坛真是帮了大忙!

【讨论】:

    猜你喜欢
    • 2015-05-13
    • 1970-01-01
    • 2019-09-27
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 2021-12-27
    相关资源
    最近更新 更多