根据列的每个元素的条件计算出现次数

时间:2014-08-07 21:54:48

标签: r count dataframe cumulative-sum

我正在分析机场的空中交通流量。我的数据集包括飞机拦截时间(离开大门)和相应的起飞时间。 我正在寻找一种有效的方法来根据飞行的阻滞时间给出的条件计算起飞事件的(累积)发生次数。

对R来说相对较新,我已经设法通过

进行编码
  1. 循环遍历我的所有数据行;
  2. 对该行中的块时间(条件事件)的数据进行子集化;和
  3. 计算(临时)数据帧的行数。
  4. 对于一个月的数据(~50,000次飞行),我的解决方案已经非常缓慢,因此分析一年或两年的较长时间框架将非常麻烦。 我没能在stackoverflow(或其他地方)上找到适用于我的问题的类似问题。我也不能让apply()sapply()正常工作。

    这是我的代码:

    ## count depeartures before own off-block
    data$CUM_DEPS <- rep(NA, nrow(data))      # initialise column for dep count
    
    for(i in 1:nrow(data)){                   # loop over the data
        data$CUM_DEPS[i] <- nrow(data[data$TAKE_OFF_TIME < data$BLOCK_OFF_TIME[i],])
    } 
    

    任何指针?

    如建议的那样,这是我创建的数据和结果列的快照。

        FLTID        TAKE_OFF_TIME       BLOCK_OFF_TIME    CUM_DEPS
    Flight1  2013-07-01 05:02:42  2013-07-01 04:51:00    0
    Flight2  2013-07-01 05:04:30  2013-07-01 04:53:52    0
    Flight3  2013-07-01 05:09:01  2013-07-01 04:55:14    0
    Flight4  2013-07-01 05:10:30  2013-07-01 05:00:57    0
    Flight5  2013-07-01 05:12:58  2013-07-01 05:00:06    0
    Flight6  2013-07-01 05:18:45  2013-07-01 05:04:14    1
    Flight7  2013-07-01 05:22:12  2013-07-01 05:03:39    1
    Flight8  2013-07-01 05:26:02  2013-07-01 05:09:32    3
    Flight9  2013-07-01 05:27:24  2013-07-01 05:19:24    6
    Flight10 2013-07-01 05:31:32  2013-07-01 05:17:05    5
    

2 个答案:

答案 0 :(得分:1)

从上面的代码中,您似乎正在进行一对多比较。

使代码变慢的原因是您基于布尔索引对数据进行了子集化 每一步。

data$CUM_DEPS <- rep(NA, nrow(data)) 
take_off_time = data$TAKE_OFF_TIME

for(i in 1:nrow(data)){
    data$CUM_DEPS[i] = sum(data$BLOCK_OFF_TIME[i] > take_off_time)
} 

这个小修改会让它快得多,虽然我不能说准确 数字,因为我没有可重复的例子。

最大的区别是我存储了日期向量&#39; take_off_time&#39;而不是 从数据帧中为每次迭代调用,而不是基于布尔值对数据进行子集化,而是对单个布尔值求和。

最重要的是假设您已正确处理日期,以便可以将其与不等式进行比较。

答案 1 :(得分:1)

你可以检查中间的位置&#34; TAKE_OFF_TIME&#34; s,每个&#34; BLOCK_OFF_TIME&#34;下降。 findInterval对此很快;以下内容看起来有效,但您可能需要检查findInterval的参数以适合您的确切问题。

findInterval(as.POSIXct(DF[["BLOCK_OFF_TIME"]]), 
             as.POSIXct(DF[["TAKE_OFF_TIME"]]))
#[1] 0 0 0 0 0 1 1 3 6 5

并且,对于记录,使用sapply

的循环
BOT = as.POSIXct(DF[["BLOCK_OFF_TIME"]])
TOT = as.POSIXct(DF[["TAKE_OFF_TIME"]])
sapply(BOT, function(x) sum(TOT < x))
#[1] 0 0 0 0 0 1 1 3 6 5

在哪里&#34; DF&#34;:

DF = structure(list(FLTID = structure(c(1L, 3L, 4L, 5L, 6L, 7L, 8L, 
9L, 10L, 2L), .Label = c("Flight1", "Flight10", "Flight2", "Flight3", 
"Flight4", "Flight5", "Flight6", "Flight7", "Flight8", "Flight9"
), class = "factor"), TAKE_OFF_TIME = structure(1:10, .Label = c("2013-07-01 05:02:42", 
"2013-07-01 05:04:30", "2013-07-01 05:09:01", "2013-07-01 05:10:30", 
"2013-07-01 05:12:58", "2013-07-01 05:18:45", "2013-07-01 05:22:12", 
"2013-07-01 05:26:02", "2013-07-01 05:27:24", "2013-07-01 05:31:32"
), class = "factor"), BLOCK_OFF_TIME = structure(c(1L, 2L, 3L, 
5L, 4L, 7L, 6L, 8L, 10L, 9L), .Label = c("2013-07-01 04:51:00", 
"2013-07-01 04:53:52", "2013-07-01 04:55:14", "2013-07-01 05:00:06", 
"2013-07-01 05:00:57", "2013-07-01 05:03:39", "2013-07-01 05:04:14", 
"2013-07-01 05:09:32", "2013-07-01 05:17:05", "2013-07-01 05:19:24"
), class = "factor"), CUM_DEPS = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 
3L, 6L, 5L)), .Names = c("FLTID", "TAKE_OFF_TIME", "BLOCK_OFF_TIME", 
"CUM_DEPS"), class = "data.frame", row.names = c(NA, -10L))