Есть ли способ перебирать данные на основе коэффициента в столбце и суммировать количество строк?

#r #loops #data-manipulation

#r #циклы #манипулирование данными

Вопрос:

У меня есть некоторые данные, в которых у меня есть несколько наблюдений одного и того же события. Основываясь на пороговом значении времени, я хочу сконденсировать наблюдения. Но я хочу знать, сколько я сгущаю (т. Е. Сколько наблюдений становится одним). Я не уверен, как перебирать мой фрейм данных таким образом, чтобы сделать это.

Я пытался написать цикл for, операторы if, while и неустанно искал в Google и stack overflow. Кажется, ничто не связано с тем, что мне нужно сделать.

вот подмножество моих данных:

 structure(list(date.time = structure(c(1465877617, 1465877774, 
1465877816, 1465877844, 1465912214, 1465912806, 1465912862, 1465914033
), class = c("POSIXct", "POSIXt"), tzone = "America/New_York"), 
    time = structure(1:8, .Label = c("00:13:37", "00:16:14", 
    "00:16:56", "00:17:24", "09:50:14", "10:00:06", "10:01:02", 
    "10:20:33"), class = "factor"), X = c(1, 1, 1, 1, 1, 1, 1, 
    1), diff_time1 = structure(c(157, 42, 28, 34370, 592, 56, 
    1171, 2820), class = "difftime", units = "secs"), diff_time2 = c(FALSE, 
    FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, TRUE), new = c("start", 
    "include", "include", "end", "start", "include", "end", "start-end"
    )), row.names = c(NA, 8L), class = "data.frame")
  

Цель состоит в том, чтобы это выглядело так, как показано ниже, но с дополнительным столбцом размера выборки для каждого «смятого» наблюдения:

 structure(list(n = 1:8, end = structure(c(1465877844, 1465912862, 
1465914033, 1465916853, 1465921999, 1465928992, 1465933159, 1465937668
), class = c("POSIXct", "POSIXt")), start = structure(c(1465877617, 
1465912214, 1465914033, 1465916853, 1465921999, 1465928647, 1465932867, 
1465937418), class = c("POSIXct", "POSIXt")), date = structure(c(16966, 
16966, 16966, 16966, 16966, 16966, 16966, 16966), class = "Date")), row.names = c(NA, 
-8L), class = c("tbl_df", "tbl", "data.frame"))
  

Ответ №1:

 library(dplyr); library(lubridate)
df %>%
  mutate(time_since_last = (date.time - lag(date.time, default = first(date.time))) / dminutes(1)) %>%
  mutate(group = 1   cumsum(time_since_last > 15)) %>% # How many times was there a 15min  gap? Each new one increments "group"
  group_by(group) %>%
  summarize(first = min(date.time), # or first(date.time) if sorted
            last  = max(date.time), # or last(date.time) if sorted
            count = n())

## A tibble: 3 x 4
#  group first               last                count
#  <dbl> <dttm>              <dttm>              <int>
#1     1 2016-06-14 00:13:37 2016-06-14 00:17:24     4
#2     2 2016-06-14 09:50:14 2016-06-14 10:01:02     3
#3     3 2016-06-14 10:20:33 2016-06-14 10:20:33     1
  

Комментарии:

1. Это как раз то, что мне было нужно! Спасибо тебе, Джон Спринг! Поскольку я новичок в программировании и очень много учусь, как вы это выяснили?

2. Я от всей души рекомендую r4ds.had.co.nz книга для ознакомления с dplyr и сопутствующими пакетами. Мне понравилось, как они позволили сразу сделать много полезного.

3. Спасибо за эту ссылку. Это выглядит действительно, действительно полезным.

4. быстрый вопрос — Мне все еще неясно, зачем вам нужна функция cumsum() во второй строке. Не удалось выяснить причину.

5. Я хотел назначить каждый непрерывный набор событий одной группе. Я определил «новую группу» так: «был ли перерыв на 15 минут или более?» Строка cumsum подсчитывает, сколько совокупных раз это происходило в строках до этого момента, поэтому все, что в group = 1 было до этого, еще не произошло, все, что в group = 2 есть после этого, произошло один раз, все, что в group = 3 есть после этого, произошло дважды и т.д. (Мы также могли бы опустить = 1 часть, но мне понравилось, что первая группа равна 1 вместо того, чтобы называться группой 0.)