计算有序数据框中的条目和下一个条目之间的差异

时间:2013-08-20 18:29:34

标签: r dataframe apply

我有一个data.frame包含来自网站日志的信息。在其他列中,data.frame包含cookie ID,时间戳和URL。现在我想计算在每个页面上花费的时间,假设一个页面被查看,直到另一个页面被相同的cookie ID加载。这就是data.frame按照Cookie ID和时间戳使用以下命令的原因:

data = data[with(data, order(cookie_id, timestamp)), ]

以下是我使用for循环计算每个页面所花费的时间的方法:

data$calc_time_spent = NA
for (i in 1:(nrow(data)-1)) {
  if (!is.na(data$cookie_id[i]) & !is.na(data$cookie_id[i+1]) & data$cookie_id[i] == data$cookie_id[i+1]) {
    data$calc_time_spent[i] = data$timestamp[i+1]-data$timestamp[i]
  }
}

不幸的是,这非常慢,所以我需要一个更复杂的解决方案,可能使用apply-function?

-

以下是一些示例数据:

cookie_id = c("5", "5", "8", "8", "8")
timestamp = as.POSIXlt(c("2005-4-19 7:01:33", "2005-4-19 7:01:35", "2005-4-19 7:01:10", "2005-4-19 7:01:23", "2005-4-19 7:01:27"))
data = data.frame(timestamp, cookie_id)

看起来像这样:

    timestamp   cookie_id
1   2005-04-19 07:01:33 5
2   2005-04-19 07:01:35 5
3   2005-04-19 07:01:10 8
4   2005-04-19 07:01:23 8
5   2005-04-19 07:01:27 8

操作后,数据应该有第三列:

    timestamp   cookie_id   calc_time_spent
1   2005-04-19 07:01:33 5   2
2   2005-04-19 07:01:35 5   NA
3   2005-04-19 07:01:10 8   13
4   2005-04-19 07:01:23 8   4
5   2005-04-19 07:01:27 8   NA

2 个答案:

答案 0 :(得分:0)

看起来你只想区分矢量。请考虑以下事项(尽管如果您提供可重复的数据,我会更有帮助)

data$calc_time_spent[2:length(data$calc_time_spent)] - 
  data$calc_time_spent[1:(length(data$calc_time_spent) - 1)]

如果要在每个Cookie ID中执行此操作,请考虑使用“plyr”软件包或data.table。使用

将这些命令包含在“ddply”包装器或“data.table”命令中应该是直截了当的。
### Data Table Approach (faster)
library(data.table)
data[, time.spent := calc_time_spent[2:.N] - calc_time_spent[1:(.N - 1)], 
     by = cookie_id]

### Plyr approach (slower)
library(plyr)
ddply(data, .(cookie_id), summarize,
      time.spent = calc_time_spent[2:length(calc_time_spent)] - 
                   calc_time_spent[1:(length(calc_time_spent) - 1)])

注意.N是Data.Table中的内置常量,它是一个长度为1的向量,报告每个“cookie_id”组中的观察数。

当然,如果需要,您还可以使用内置函数,例如“diff”。

答案 1 :(得分:0)

这是一个解决方案。这是一个黑客。我仍然有兴趣知道如何将函数一次应用于两行,并且还有一个条件语句,说“如果是SOMETHING,那么使用NA”。

data$timestamp_next = c(data$timestamp[2:length(data$timestamp)], data$timestamp[1])
data$time_on_page = data$timestamp_next - data$timestamp
data$cookie_id_int = as.integer(data$cookie_id)
data$cookie_id_int_next = c(data$cookie_id_int[2:length(data$cookie_id_int)], data$cookie_id_int[1])
data$cookie_id_same_as_next = data$cookie_id_int == data$cookie_id_int_next
data$time_on_page[data$cookie_id_same_as_next == FALSE | is.na(data$cookie_id_same_as_next)] = NA
data$cookie_id_int = NULL
data$cookie_id_int_next = NULL
data$cookie_id_same_as_next = NULL