2013-08-20 4 views
0

У меня есть data.frame, содержащий информацию из журнала сайта. Среди других столбцов data.frame содержит идентификатор файла cookie, временную метку и URL-адрес. Теперь я хочу вычислить время, затрачиваемое на каждую страницу, при условии, что страница просматривается до тех пор, пока другая страница не будет загружена одним и тем же идентификатором файла cookie. Поэтому data.frame заказана печенья 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?

-

Вот несколько примеров данных:

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

Что-то вроде 'ave (данные $ timestamp, data $ cookie_id, FUN = diff)'? Укажите [воспроизводимый пример] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – sgibb

+0

Теперь я представил воспроизводимый пример. – elgehelge

ответ

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», если хотите.

+0

При попытке решения таблицы я получаю следующую ошибку: Ошибка в '.data.frame' (data,,': = '(time.spent, calc_time_spent [2 :. N] -: неиспользованный аргумент (by = "cookie_id") Btw. Я привел пример сейчас. – elgehelge

+0

Сообщение отредактировано. Переменная «by» не обязательно должна указываться. – Andreas

+1

Я думаю, было бы безопаснее использовать diff в случае '.N = 1' – mnel

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 
Смежные вопросы