Создание столбца часов из данных ЧЧ: ММ: СС в R

Я пытаюсь создать столбец данных, в котором будет указан только час каждого наблюдения, на основе данных времени, отформатированных как ЧЧ:ММ:СС в R.

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

Пример вектора времени: a <- c(22:00:03, 22:00:05, 22:00:07, 22:00:09)
Желаемый результат: [1] 22 22 22 22

Мой набор данных очень велик, поэтому создание отдельных векторов с почасовыми наблюдениями требует много времени.

Я пытался изучить функцию «смазка», но не нашел решения.

Любая помощь приветствуется!


106
2

Ответы:

Решено

Вы можете использовать регулярное выражение, чтобы получить первые две цифры:

as.numeric(gsub("(^\\d{2}).*", "\\1", a))
# [1] 22 22 22 22

Преобразуйте его в POSIXlt, а затем отформатируйте, чтобы извлечь час:

as.numeric(format(strptime(a, "%H:%M"), "%H"))
# [1] 22 22 22 22

В lubridate вы можете преобразовать его с помощью hms(), который преобразует вектор символов в формате HH:MM в объект точки, а затем извлекает компонент часа:

library(lubridate)

hour(hms(a))
# [1] 22 22 22 22

Пакет dttr2 имеет аналогичный синтаксис для смазки:

library(dttr2)

dtt_hour(dtt_time(a))
# [1] 22 22 22 22

Разделите его на : и возьмите первый элемент:

as.numeric(sapply(strsplit(a, ":", fixed = TRUE), `[[`, 1))
# [1] 22 22 22 22

stringr реализовано str_split_i() в версии пакета 1.5.0, что позволяет разбивать и выбирать элемент по индексу:

library(stringr)

as.numeric(str_split_i(a, ":", 1))
# [1] 22 22 22 22

Пакет strex может упростить использование общих регулярных выражений для извлечения всего, что происходит до первого совпадения с шаблоном:

library(strex)

as.numeric(str_before_first(a, ":"))
# [1] 22 22 22 22

Используйте пакет datetime, чтобы превратить его в объект времени, преобразовать его в числовое значение (которое вернет секунды) и преобразовать в часы:

library(datetime)

as.numeric(as.time(a)) / (60 * 60)
# [1] 22 22 22 22

Попробуйте sub

a <- c("22:00:03", "22:00:05", "22:00:07", "22:00:09")

sub <- as.numeric(sub(":.*", "", a))
## [1] 22 22 22 22

Сравнивая это с опубликованными (плюс решениями difftime и chron) в порядке медианного времени (сначала самое быстрое), substr был самым быстрым, но решения substr и gsub предполагают нулевой заполненный час, тогда как другие решения, которые решают общую проблему, этого не делают. допускает ненулевой заполненный час, суб-самый быстрый. Все три самых быстрых общих решения являются базовыми. Решения chron и dttr2 кажутся наиболее читабельными или, возможно, смазывающими, в зависимости от того, считаете ли вы, что time или hms более читабельны.

library(lubridate)
library(dttr2)
library(strex)
library(datetime)
library(chron)
library(microbenchmark)

a <- c("22:00:03", "22:00:05", "22:00:07", "22:00:09")

microbenchmark(
  substr = substr(a, 1, 2), # assumes 0-filled hour
  sub = as.numeric(sub(":.*", "", a)), 
  gsub = as.numeric(gsub("(^\\d{2}).*", "\\1", a)), # assumes 0-filled hour
  strsplit = as.numeric(sapply(strsplit(a, ":", fixed = TRUE), `[[`, 1)),
  POSIXlt = as.numeric(format(strptime(a, "%H:%M"), "%H")),
  datetime = as.numeric(as.time(a)) / (60 * 60),
  difftime = as.integer(as.difftime(a), unit = "hour"),
  chron = chron::hours(times(a)),
  strex = as.numeric(str_before_first(a, ":")),
  lubridate = lubridate::hour(hms(a)),
  dttr2 = dtt_hour(dtt_time(a))
)

предоставление

Unit: microseconds
      expr    min      lq     mean  median      uq     max neval
    substr    4.4    7.90    8.957    8.90   10.20    19.4   100
       sub   37.5   45.90   53.228   51.40   60.60    91.9   100
      gsub   56.1   71.35   81.032   78.95   90.60   147.5   100
  strsplit   73.4   89.70   98.007  100.80  103.30   150.6   100
   POSIXlt  133.8  148.80  164.063  165.20  177.00   214.9   100
  datetime  193.1  219.90  245.828  233.05  258.50   433.0   100
  difftime  290.9  325.35  357.287  354.55  374.75   613.5   100
     chron  291.1  320.50  357.119  367.05  379.15   573.7   100
     strex  742.2  815.10  916.158  921.70  953.60  1602.0   100
 lubridate 1007.9 1100.60 1262.641 1176.25 1225.85  7782.4   100
     dttr2 8321.5 8574.90 8841.866 8724.10 8897.80 13899.2   100