2016-12-20 3 views
0

У меня есть некоторые данные отслеживания, где я хочу, чтобы вычислить разницу во времени между каждой точкой, которую я могу сделать с этим:Как перекомпилировать список, разделенный по уровню фактора, на исходный фрейм данных?

# prep the data 
ID = c(rep("A",5), rep("B",5)) 
DateTime = c("2014-09-25 08:39:45", "2014-09-25 08:39:48", "2014-09-25 08:40:44", "2014-09-25 09:04:00","2014-09-25 09:04:10", "2014-09-25 08:33:32", "2014-09-25 08:34:41", "2014-09-25 08:35:24", "2014-09-25 09:04:00", "2014-09-25 09:04:09") 
speed = c(1:10) 
df = data.frame(ID,DateTime,speed, stringsAsFactors = FALSE) 
df$DateTime<-as.POSIXct(df$DateTime, tz = "UTC") 

# function to calculate time differences 
timeCheck<-function(df) { 
    sapply(1:(nrow(df) - 1), function(i){ 
    timeDiff<- difftime(df$DateTime[i+1], df$DateTime[i], units = "sec") 
    return(timeDiff) 
    }) 
} 
# preserve order of factor levels 
df$ID <- factor(df$ID, levels=unique(df$ID)) 

# apply the function by ID 
timeDiffData<-sapply(split(df, df$ID), timeCheck) 

Я хочу, чтобы иметь возможность добавить новый столбец временных разниц в первоначальной dataframe но, конечно, этот список имеет разную длину, потому что функция не вычисляет разницу во времени от себя.

Затем я хочу использовать эти временные разницы в новой функции для разделения треков, если разница больше определенного значения (например, 100 секунд для примера), и идентификатор отражает это.

Так что в конце концов у меня было бы 4 уровня для моего идентификационного столбца, и разнесение произойдет, когда разница во времени> 100 секунд.

В результате dataframe должен выглядеть примерно так:

# what it should look like 
ID = c(rep("A",3),rep("A1",2) , rep("B",3), rep("B1",2)) 
DateTime = c("2014-09-25 08:39:45", "2014-09-25 08:39:48", "2014-09-25 08:40:44", "2014-09-25 09:04:00","2014-09-25 09:04:10", "2014-09-25 08:33:32", "2014-09-25 08:34:41", "2014-09-25 08:35:24", "2014-09-25 09:04:00", "2014-09-25 09:04:09") 
speed = c(1:10) 
timeDiff<-c(NA,3,56,1396,10,NA,69,43,1716,9) 
newdf = data.frame(ID,DateTime,speed,timeDiff, stringsAsFactors = FALSE) 
newdf$DateTime<-as.POSIXct(df$DateTime, tz = "UTC") 
newdf 

ответ

0

Действительно ваша операция имеет три этапа:

  • Сгруппируйте данные по ID
  • Compute временных различия между каждой временной меткой в ​​вашей группе (первая разность времени равна NA)
  • Создайте новый идентификатор, который подсчитывает количество задержек предшествующего времени, которые являются большими (например,> 100 секунд)

Это можно сделать довольно просто с dplyr, используя group_by для группировки и mutate для вычисления новых переменных в каждой группе:

library(dplyr) 
df %>% 
    group_by(ID) %>% 
    mutate(timeDiff = c(NA, difftime(tail(DateTime, -1), head(DateTime, -1), units="sec"))) %>% 
    mutate(newID = paste0(ID, cumsum(!is.na(timeDiff) & timeDiff > 100))) %>% 
    ungroup() 
# A tibble: 10 × 5 
#  ID   DateTime speed timeDiff newID 
# <chr>    <dttm> <int> <dbl> <chr> 
# 1  A 2014-09-25 08:39:45  1  NA A0 
# 2  A 2014-09-25 08:39:48  2  3 A0 
# 3  A 2014-09-25 08:40:44  3  56 A0 
# 4  A 2014-09-25 09:04:00  4  1396 A1 
# 5  A 2014-09-25 09:04:10  5  10 A1 
# 6  B 2014-09-25 08:33:32  6  NA B0 
# 7  B 2014-09-25 08:34:41  7  69 B0 
# 8  B 2014-09-25 08:35:24  8  43 B0 
# 9  B 2014-09-25 09:04:00  9  1716 B1 
# 10  B 2014-09-25 09:04:09 10  9 B1 
0

Один ответ, который работал отлично был удален автором. Вот он для потомков:

library(data.table) 
setDT(df)[ , ID2 := paste0(ID, cumsum(c(0, diff(DateTime)) > 100)), by = ID] 
Смежные вопросы