Отметить строки с интервалом перекрытия в r - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть фрейм df, содержащий данные просмотра телевизора, я хотел бы запустить проверку QC для перекрывающегося просмотра. Скажем, в один и тот же день, в одном домохозяйстве, для каждого человека каждая минута должна быть зачислена только на одну станцию ​​или канал.

например, я хотел бы отметить строки 8, 9, потому что кажется невозможным, чтобы человек в уникальном доме смотрел две телевизионные станции (62,67) одновременно (start_hour_minute). Мне интересно, есть ли способ пометить эти строки? Сортировка минут за минутой, просмотр отдельных людей по дням.

df <- data.frame(stringsAsFactors=FALSE,
         date = c("2018-09-02", "2018-09-02", "2018-09-02", "2018-09-02",
                  "2018-09-02", "2018-09-02", "2018-09-02", "2018-09-02",
                  "2018-09-02"),
         householdID = c(18101276L, 18101276L, 18102843L, 18102843L, 18102843L,
                  18102843L, 18104148L, 18104148L, 18104148L),
   Station_id = c(74L, 74L, 62L, 74L, 74L, 74L, 62L, 62L, 67L),
        IndID = c("aa", "aa", "aa", "aa", "aa", "aa", "aa", "aa", "aa"),
        Start = c(111300L, 143400L, 030000L, 034900L, 064400L, 070500L, 060400L,
                  075100L, 075100L),
          End = c(111459L, 143759L, 033059L, 035359L, 064759L, 070559L, 060459L,
                  81559L, 81559L),
   start_hour_minute = c(1113L, 1434L, 0300L, 0349L, 0644L, 0705L, 0604L, 0751L, 0751L),
     end_hour_minute = c(1114L, 1437L, 0330L, 0353L, 0647L, 0705L, 0604L, 0815L, 0815L))

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Пакет lubridate имеет объект класса inteval и функцию %within%, которая проверяет, находится ли отметка времени в пределах интервала. Вы можете использовать это, чтобы получить флаги.

Используя фиктивные данные, которые вы предоставили выше ...

data_out <- df %>% 
# Get the hour, minute, and second values as standalone numerics.
mutate(
    date = ymd(date),
    Start_Hour = floor(Start / 10000),
    Start_Minute = floor((Start - Start_Hour*10000) / 100),
    Start_Second = (Start - Start_Hour*10000) - Start_Minute*100,
    End_Hour = floor(End / 10000),
    End_Minute = floor((End - End_Hour*10000) / 100),
    End_Second = (End - End_Hour*10000) - End_Minute*100,
# Use the hour, minute, second values to create a start-end timestamp.
    Start_TS = ymd_hms(date + hours(Start_Hour) + minutes(Start_Minute) + seconds(Start_Second)),
    End_TS = ymd_hms(date + hours(Start_Hour) + minutes(Start_Minute) + seconds(Start_Second)),
# Create an interval object.
    Watch_Interval = interval(start = Start_TS, end = End_TS)
) %>% 
# Group by the IDs.
group_by(householdID, Station_id) %>% 
# Flag where the household's interval overlaps with another time.
mutate(
    overlap_flag = case_when(
        sum(Start_TS %within% as.list(Watch_Interval)) == 0 ~ 0,
        sum(Start_TS %within% as.list(Watch_Interval)) > 0 ~ 1,
        TRUE ~ NA_real_
    )
) %>% 
# dplyr doesn't play nice with interval objects, so we should remove Watch_Interval.
select(-Watch_Interval)

См. Отмеченные значения, используя data_out %>% filter(overlap_flag == 1).

Примечание: Пакеты dplyr и lubridate не всегда хорошо играют вместе, особенно в старых версиях. Вам может потребоваться обновить версии пакетов для каждого.

0 голосов
/ 12 сентября 2018

Вы можете просто сгруппировать по переменным, которые, по вашему мнению, должны соответствовать отдельным строкам (например, комбинации домохозяйства-дата-минута), а затем подсчитать строки (или уникальные значения в Station_id) и добавить flag = 1, если эта строкадолжен быть помечен, иначе flag = 0

df %>% 
    group_by(date, householdID, start_hour_minute) %>% 
    mutate(flag = if_else(n() == 1, 0, 1))

В качестве альтернативы, если вы хотите, чтобы все соответствовали другим переменным, кроме Station_id, вы можете сделать

df %>% 
    group_by_at(vars(-Station_id)) %>% 
    mutate(flag = if_else(n() == 1, 0, 1))
...