dplyr滞后传递向量而不是单值到调用函数

时间:2015-08-12 15:15:20

标签: r dplyr

我有一个像这样的数据框:

> df
  threadId          threadTime
1        1 2014-07-08 18:28:29
2        1 2014-07-08 18:46:09
3        2 2014-07-10 10:14:42
4        2 2014-07-10 10:30:49
5        3 2014-07-10 11:19:27
6        3 2014-07-10 11:45:23
> str(df)
'data.frame':   6 obs. of  2 variables:
 $ threadId  : num  1 1 2 2 3 3
 $ threadTime: POSIXct, format: "2014-07-08 18:28:29" "2014-07-08 18:46:09" ...

我正在使用一个简单的函数调用(这个函数的作用并不重要):

someFunc <- function(t1, t2) { cat(t1); cat('\n'); return(1)}

当我调用函数来改变数据框上的新列时,如下所示,我看到函数是使用threadTime值的向量而不是独立的滞后行和当前行的值来调用的。我错过了什么?

df %>% group_by(threadId) %>% mutate(blah = someFunc(lag(threadTime), threadTime))

我期待t1是滞后行中的时间,而t2是当前行中的时间。当然,该组的第一行将具有NA的滞后值,我很好,可以在我的函数中检查它。

对于'df'中的'三个组',该函数调用的输出仅对于t1参数如下。使用'lag(threadTime)'和'threadTime'的连接值调用该函数。

t1 = NA 1404858509
t1 = NA 1405001682
t1 = NA 1405005567

更新

原来我的功能/需要完全重要。更新问题。我想计算滞后行时间值之间的工作日和小时数。所以,我使用的函数如下(onDays是工作日,周末+假期,onHours是营业时间):

workingHours <- function(t1, t2) {
  elapsedTime <- seq.POSIXt(from = t1, to = t2, by = 'hour')
  elapsedTime <- elapsedTime[as.Date(elapsedTime) %in% onDays &
                               as.numeric(format(elapsedTime, '%H')) %in%
                               onHours]
  return(length(elapsedTime))
}

在这种情况下,seq.POSIXt不会为'from'和'to'采用向量,因此我不能使用向量化的lag()值。有没有比'循环'或使用某种apply()调用更好的选择,这可能只比循环略有改进?

1 个答案:

答案 0 :(得分:2)

评论太长了,所以我发帖作为答案......

您的常规lag()语法应该有效。我会检查你是否没有出现屏蔽问题,其他一些软件包提供的lag函数与dplyr不同。您可以随时明确并致电dplyr::lag以确定。

以下是内置数据的一些代码,用于演示 的基本构思

mtcars %>% 
  arrange(cyl, mpg) %>%
  group_by(cyl) %>%
  mutate(mpgmpg = paste(lag(mpg), mpg, sep = "!"))

# Source: local data frame [32 x 12]
# Groups: cyl
#
#     mpg cyl  disp  hp drat    wt  qsec vs am gear carb    mpgmpg
# 1  21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2   NA!21.4
# 2  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1 21.4!21.5
# 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 21.5!22.8
# 4  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 22.8!22.8
# 5  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 22.8!24.4
# 6  26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2   24.4!26

同样,使用功能的修改版本:

someFunc <- function(t1, t2) { cat(t1); cat("\n"); cat(t2); cat('\n\n'); return(1)}

这就是我所期望的,也是我得到的:

mtcars %>% arrange(cyl, mpg) %>% group_by(cyl) %>%
  mutate(mpgmpg = someFunc(lag(mpg), mpg))
# NA 21.4 21.5 22.8 22.8 24.4 26 27.3 30.4 30.4 32.4
# 21.4 21.5 22.8 22.8 24.4 26 27.3 30.4 30.4 32.4 33.9

# NA 17.8 18.1 19.2 19.7 21 21
# 17.8 18.1 19.2 19.7 21 21 21.4

# NA 10.4 10.4 13.3 14.3 14.7 15 15.2 15.2 15.5 15.8 16.4 17.3 18.7
# 10.4 10.4 13.3 14.3 14.7 15 15.2 15.2 15.5 15.8 16.4 17.3 18.7 19.2
# ...

这是因为lag是矢量化的,someFunc是矢量化的,这是一件好事!它似乎符合您的描述:

  

我期待t1在滞后行中是时间,而t2是当前行中的时间

您可以看到滞后值(顶行)如何与当前值(底行)配对。

如果这不是您想要的,请编辑您的问题以显示所需行为,最好是内置数据集或dput()或模拟数据。< / p>