Определите начало и конец поездки в R - PullRequest
2 голосов
/ 04 апреля 2020

Я хотел бы определить продолжительность действия, которое начинается в t1 и заканчивается в t7. Отправной точкой является t1, которая записывает возникновение активности в моменты времени t1_1, t1_2, t1_3 и так далее. Например, в случае идентификатора 12 активность произошла в t1_2 и t1_3 (я хотел бы сохранить это) t2_2 (так как до и после того, как я не заинтересован в этой активности, нет активности), t3_1 (так же, как t2_2), t3_3, t4_2, t5_2, t6_1, t6_2, t6_3 и t7_3. Я хотел бы идентифицировать для начала и конца все идентификаторы, в которых произошла активность, продолжительность и наиболее частые из них.

Вход:

id t1_1 t1_2 t1_3 t2_1 t2_2 t2_3 t3_1 t3_2 t3_3 t4_1 t4_2 t4_3 t5_1 t5_2 t5_3 t6_1 t6_2 t6_3 t7_1 t7_2 t7_3
12  0    1     1    0     1   0    1    0    1    0    1    0    0    1    0     1   1     1   0      0  1
123 0    0     0    1     1   1    0    0    0    1    1    1    1    1    1     0   0     0    1     1  1
 10  1   1     1    1     1    1    1   1    1    1    1    1    1    1    1     1   1     1    1     1  1   

Выход для идентификатора 12

Id    Start/End    Duration  Frequency
12   t1_1, t1_3     2         1
12   t6_1, t6_3     3         1

Один из способов решить эту проблему - использовать библиотеку биокондуктора, но есть ли лучшее решение?

Пример данных

df1 <- structure(list(id = c(12L, 123L, 10L), t1_1 = c(0L, 0L, 1L), 
            t1_2 = c(1L, 0L, 1L), t1_3 = c(1L, 0L, 1L), t2_1 = c(0L, 
            1L, 1L), t2_2 = c(1L, 1L, 1L), t2_3 = c(0L, 1L, 1L), t3_1 = c(1L, 
            0L, 1L), t3_2 = c(0L, 0L, 1L), t3_3 = c(1L, 0L, 1L), t4_1 = c(0L, 
            1L, 1L), t4_2 = c(1L, 1L, 1L), t4_3 = c(0L, 1L, 1L), t5_1 = c(0L, 
            1L, 1L), t5_2 = c(1L, 1L, 1L), t5_3 = c(0L, 1L, 1L), t6_1 = c(1L, 
            0L, 1L), t6_2 = c(1L, 0L, 1L), t6_3 = c(1L, 0L, 1L), t7_1 = c(0L, 
            1L, 1L), t7_2 = c(0L, 1L, 1L), t7_3 = c(1L, 1L, 1L)), 
            class = "data.frame", row.names = c(NA, 
        -3L))

Ответы [ 2 ]

1 голос
/ 04 апреля 2020
library('data.table')
df1 <- melt(setDT(df1), id.var = 'id')
df1[, c('time', 'subtime') := tstrsplit(as.character(variable), "_", fixed = TRUE)]
df2 <- df1[, rle(value), by = .(id, time)][lengths > 1 & values == 1, ]
df3 <- df1[df2, on = c('id', 'time')]
df3 <- df3[, .(`Start/End` = paste0(time, '_', c(min(subtime), max(subtime)), collapse = " - "), 
                           Duration = unique(lengths)), 
           by = .(id, time)]
df3[, Frequency := .N, by = .(id, `Start/End`)]
df3[, time := NULL]
df3[order(id), ]

#     id   Start/End Duration Frequency
# 1:  10 t1_1 - t1_3        3         1
# 2:  10 t2_1 - t2_3        3         1
# 3:  10 t3_1 - t3_3        3         1
# 4:  10 t4_1 - t4_3        3         1
# 5:  10 t5_1 - t5_3        3         1
# 6:  10 t6_1 - t6_3        3         1
# 7:  10 t7_1 - t7_3        3         1
# 8:  12 t1_1 - t1_3        2         1
# 9:  12 t6_1 - t6_3        3         1
# 10: 123 t2_1 - t2_3        3         1
# 11: 123 t4_1 - t4_3        3         1
# 12: 123 t5_1 - t5_3        3         1
# 13: 123 t7_1 - t7_3        3         1
1 голос
/ 04 апреля 2020

Мы конвертируем в «длинный» формат с помощью pivot_longer, затем создаем группирующую переменную с rleid (из data.table) на основе появления похожих соседних элементов в «значении», filter в строках, где 'value' равно 1, сгруппированы по 'id', 'grp', мы сохраняем только строки, в которых счетчик частоты больше 1, summarise на paste в first и *1008* и last элементы name также получают количество (n()) и arrange при необходимости

library(dplyr)
library(tidyr)
library(stringr)
library(data.table)
df1 %>% 
   pivot_longer(cols = -id) %>% 
   mutate(grp = rleid(value)) %>%
   filter(as.logical(value)) %>%
   group_by(id, grp) %>% 
   filter(n() > 1) %>%
   summarise(Start_End = str_c(first(name), last(name), sep=", "),
       Duration = n()) %>%
   arrange(id, grp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...