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

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

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

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

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

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

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

Пожалуйста, прочитайте о как создать отличный воспроизводимый пример R и соответствующим образом обновите свой вопрос. Включите образец ваших данных, вставив вывод dput(<your data frame>) в свое сообщение или dput(head(<your data frame>)), если у вас большой фрейм данных. Если вы не можете опубликовать свои данные, укажите код для создания репрезентативных данных. Также укажите код, который вы пробовали, все соответствующие ошибки и ожидаемый результат.

LMc 28.06.2024 22:58

Вы получите больше помощи, если опубликуете воспроизводимый пример и ожидаемый результат.

LMc 28.06.2024 22:59
substr(a, 1, 2)
Onyambu 28.06.2024 23:23
library(readr) parse_number(a)
TarJae 28.06.2024 23:23
library(data.table); hour(as.ITime(a))
Onyambu 28.06.2024 23:26
library(lubridate) a <- hms(a) hour(a)
TarJae 28.06.2024 23:27

Если вы используете пакет lubridate для анализа дат. Вы можете использовать lubridate::hour, чтобы узнать часы. Нравится: x <- lubridate::hms( c("22:00:03", "22:00:05", "22:00:07", "22:00:09")) %>% lubridate::hour()

ryanzom 28.06.2024 23:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
106
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

Я использовал вторую функцию, используя as.numeric, format и strptime, и это сработало отлично.

anzac21 02.07.2024 19:53

Попробуйте 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

Можно добавить as.numeric(substr(a, 1, 2)), это быстрее на порядок. Предполагая, что часы имеют две цифры, как обычно и должно быть.

jay.sf 30.06.2024 08:57

Добавили, но это предполагает нулевой заполненный час, тогда как другие (кроме gsub) этого не делают, поэтому sub по-прежнему остается самым быстрым из общих решений.

G. Grothendieck 30.06.2024 14:35

Другие вопросы по теме