如何使用多个条件和日期时间在R中编写for循环

时间:2015-01-03 00:45:57

标签: r datetime if-statement for-loop

我正在尝试编写一个for循环,它将对符合特定条件的数据进行子集化。相隔不到7分钟的日期/时间,也有两个不同的方向(向上和向下或向下和向上),长度差异小于4.这就是数据集的样子。

样本数据

>    DateTime  Length  Direction
>    4/3/2014 14:43 90  Up
>    4/3/2014 14:45 92  Down
>    4/3/2014 14:46 97  Up
>    4/3/2014 14:49 199 Up
>    4/3/2014 14:50 200 Up
>    4/3/2014 14:55 202 Down

我格式化了日期:

data$DateTime<-as.POSIXlt(data$DateTime,format="%m/%d/%y %H:%M",tz="US/Pacific")

我以为我可以在for循环中使用difftime来计算时间差,然后为其他条件添加if语句,但是我无法设置它。  任何人都可以提供任何帮助吗?

1 个答案:

答案 0 :(得分:1)

这是一个很好的例子,说明for循环没问题,但矢量化更快,可以说更简单。

使用您的数据集,实际检查它有点困难,因为除了第一行之外的所有内容都符合您的条件(因为所有行的差异小于4分钟或切换方向)。

从您的数据开始:

data <- data.frame(
    DateTime = strptime(c("04/03/2014 14:43", "04/03/2014 14:45", "04/03/2014 14:46", "04/03/2014 14:49", "04/03/2014 14:50", "04/03/2014 14:55"), '%m/%d/%Y %H:%M'), 
    Length = c(90L, 92L, 97L, 199L, 200L, 202L),
    Direction = c("Up", "Down", "Up", "Up", "Up", "Down"))

基本功能

首先,difftime需要两个单独的参数,因此与diff不同,我们需要明确。幸运的是,它接受两个向量而不仅仅是两个值,因此我们可以对nhead使用否定tail(请参阅help(head))。 (这也可以通过as.numeric转换日期来轻松完成,但我认为您更愿意保留这些课程。)

(minutesDiff <- c(Inf, difftime(tail(data$DateTime, n = -1),
                                head(data$DateTime, n = -1),
                                units = 'mins')))
## [1] Inf   2   1   3   1   5

(dirToggle <- c(FALSE, tail(data$Direction, n = -1) != head(data$Direction, n = -1)))
## [1] FALSE  TRUE  TRUE FALSE FALSE  TRUE

## these meet your criteria
which((minutesDiff < 4) | ((minutesDiff < 7) & dirToggle) )
## [1] 2 3 4 5 6

你说&#34;过滤&#34;这可以解释为任何一种方式,但它很容易切换。

data[(minutesDiff < 4) | ((minutesDiff < 7) & dirToggle), ]
##              DateTime Length Direction
## 2 2014-04-03 14:45:00     92      Down
## 3 2014-04-03 14:46:00     97        Up
## 4 2014-04-03 14:49:00    199        Up
## 5 2014-04-03 14:50:00    200        Up
## 6 2014-04-03 14:55:00    202      Down

data[! ((minutesDiff < 4) | ((minutesDiff < 7) & dirToggle)), ]
##              DateTime Length Direction
## 1 2014-04-03 14:43:00     90        Up

使用dplyr

如果您喜欢冒险并希望与dplyr一起玩,那可能会有这样的效果:

library(dplyr)
data %>%
    mutate(minutesDiff = c(Inf, difftime(tail(data$DateTime, n = -1),
                                         head(data$DateTime, n = -1),
                                         units = 'mins')),
           dirToggle = c(FALSE, tail(Direction, n = -1) != head(Direction, n = -1))) %>%
    filter(((minutesDiff < 7) & dirToggle) | (minutesDiff < 4)) %>%
    select(DateTime, Length, Direction)
##              DateTime Length Direction
## 1 2014-04-03 14:45:00     92      Down
## 2 2014-04-03 14:46:00     97        Up
## 3 2014-04-03 14:49:00    199        Up
## 4 2014-04-03 14:50:00    200        Up
## 5 2014-04-03 14:55:00    202      Down

(如果您希望在适当的位置看到mutate d列,请在结尾处删除select子句。)