مقارنة فترات التواريخ داخل نفس إطار البيانات

لقد بحثت في جميع أنحاء والعثور على أسئلة مماثلة ولكن يمكن أن تجعلها تعمل على بياناتي.

لدي إطار بيانات يحتوي على تواريخ البدء والانتهاء ، بالإضافة إلى العديد من العوامل الأخرى. من الناحية المثالية ، يجب أن يكون تاريخ بدء الصف متخلفًا عن تاريخ انتهاء أي صف سابق ، ولكن البيانات تتكرر في نهايات أو نهايات ، وأحياناً تتداخل فواصل التواريخ.

حاولت تقديم مثال مستنسخ:

df = data.frame(start=c("2018/04/15 9:00:00","2018/04/15 9:00:00","2018/04/16 10:20:00","2018/04/16 15:30:00",
                   "2018/04/17 12:40:00","2018/04/17 18:50:00"),
                end=c("2018/04/16 8:00:00","2018/04/16 7:10:00","2018/04/17 18:20:00","2018/04/16 16:30:00",
                   "2018/04/17 16:40:00","2018/04/17 19:50:00"),
                value=c(10,15,11,13,14,12))

تمكنت من إزالة التكرار (نهاية أو تواريخ البدء) ، ولكن لا يمكنني إزالة الفواصل الزمنية المتداخلة. أريد إنشاء حلقة "تنظف" الفواصل الزمنية الموجودة في أي فاصل زمني أكبر. لذا تبدو النتائج كما يلي:

result = df[c(1,3,6),]

ظننت أنني يمكن أن أقوم بحلقة من شأنها أن "تنظف" كل من التكرارات والفترات المتداخلة ، ولكن لا يمكنني جعلها تعمل.

أي اقتراحات؟

0
إذا فهمت سؤالك بشكل صحيح ، فيجب أن يكون من الممكن group_by تاريخ البدء و الشريحة لتاريخ الانتهاء الأقصى لتاريخ البدء المحدد المطلوب (dplyr) ؛ df٪>٪ mutate (s1 = strftime (start ، "٪ Y-٪ m-٪ d"))٪>٪ group_by (s1)٪>٪ شريحة (which.max (end))
وأضاف المؤلف count, مصدر

2 إجابة

تناسب حزمة data.table هذا النوع من المشاكل باستخدام وظيفة الربط المتداخلة foverlaps (مستوحاة من وظيفة findOverlaps من حزمة Bioconductor IRanges) ومن ثم مضاد للانضمام ( بناء جملة data.table هو B [! A، on] ) لإزالة تلك الفواصل الداخلية.

library(data.table)
cols <- c("start", "end")
setDT(df)
df[, (cols) := lapply(.SD, function(x) as.POSIXct(x, format="%Y/%m/%d %H:%M:%s")), .SDcols=cols]
setkeyv(df, cols)
anti <- foverlaps(df, df, type="within")[start!=i.start | end!=i.end | value!=i.value]
df[!anti, on=.(start=i.start, end=i.end, value=i.value)]

#                  start                 end value
# 1: 2018-04-15 09:00:00 2018-04-16 08:00:00    10
# 2: 2018-04-16 10:20:00 2018-04-17 18:20:00    11
# 3: 2018-04-17 18:50:00 2018-04-17 19:50:00    12
0
وأضاف
شكرا جزيلا! استغرق الأمر بعض الجهد لجعله يعمل لأن مجموعة البيانات الخاصة بي تحتوي على الكثير من "القيم" ، ولكن يبدو أنها تعمل بشكل مثالي: D
وأضاف المؤلف NeReiS, مصدر

النهج البديل هو استخدام ٪ داخل٪ من حزمة lubridate() :

library(lubridate)
# transform characters to dates
start_time <- as_datetime(df[ , "start"], tz = "UTC")
end_time <- as_datetime(df[ , "end"], tz = "UTC")
# construct intervals
start_end_intrvls <- interval(start_time, end_time)
# find indices of the non-within intervals
not_within <- !(sapply(FUN = function(i) any(start_end_intrvls[i] %within% start_end_intrvls[-i]), 
    X = seq(along.with = df[ , "start"])))
df[not_within, ]
#                 start                 end value
# 1  2018/04/15 9:00:00  2018/04/16 8:00:00    10
# 3 2018/04/16 10:20:00 2018/04/17 18:20:00    11
# 6 2018/04/17 18:50:00 2018/04/17 19:50:00    12

تحديث

تتسبب الدالة as_datetime() في حدوث خطأ عندما يتم تطبيقها على مادة التبويب:

as_datetime(tibble("2018/04/15 9:00:00"), tz = "UTC")
  خطأ في as.POSIXct.default (x):
  لا أعرف كيفية تحويل "س" إلى الطبقة "POSIXct"
</القانون> </قبل>

قد يتم تعديل الحل أعلاه لحل هذه المشكلة باستبدال as_datetime() بـ as.POSIXlt() :

df_tibble <- tibble(start=c("2018/04/15 9:00:00","2018/04/15 9:00:00","2018/04/16 10:20:00",
    "2018/04/16 15:30:00", "2018/04/17 12:40:00","2018/04/17 18:50:00"),
     end=c("2018/04/16 8:00:00","2018/04/16 7:10:00","2018/04/17 18:20:00","2018/04/16 16:30:00",
     "2018/04/17 16:40:00","2018/04/17 19:50:00"), value=c(10,15,11,13,14,12))

start_time_lst <- lapply(FUN = function(i) as.POSIXlt(as.character(df_tibble[i , "start"]),
    tz = "UTC"),
    X = seq(along.with = unlist(df_tibble[ , "start"])))
end_time_lst <- lapply(FUN = function(i) as.POSIXlt(as.character(df_tibble[ i, "end"]),
    tz = "UTC"),
    X = seq(along.with = unlist(df_tibble[ , "end"])))
start_end_intrvls <- lapply(function(i) interval(start_time_lst[[i]] , end_time_lst[[i]]), 
    X = seq(along.with = unlist(df_tibble[ , "start"])))
not_within <- sapply(function(i) !(any(unlist(Map(`%within%`, 
    start_end_intrvls[[i]], start_end_intrvls[-i])))), 
    X = seq(along.with = unlist(df_tibble[ , "start"])))
0
وأضاف
لا أستطيع جعله يعمل ، أحصل على "خطأ في as.POSIXct.default (x): لا أعرف كيفية تحويل الخطأ" x "إلى الطبقة" POSIXct "
وأضاف المؤلف NeReiS, مصدر
وأضاف المؤلف NeReiS, مصدر
NeReiS ، ستحتاج إلى تمرير format = "٪ Y /٪ m /٪ d٪ H:٪ M:٪ S" إلى as_datetime وظيفة
وأضاف المؤلف chinsoon12, مصدر
وأضاف المؤلف Ekatef, مصدر