2016-10-31 1 views
1

Мой dataframe имеет временную метку с и без секунд, и случайное использование 0 перед месяцев и часов, то есть 01 или 1R: извлечь час из переменной формат временной метки

library(tidyverse) 
df <- data_frame(cust=c('A','A','B','B'), timestamp=c('5/31/2016 1:03:12', '05/25/2016 01:06', 
              '6/16/2016 01:03', '12/30/2015 23:04:25')) 
cust  timestamp 
A  5/31/2016 1:03:12 
A  05/25/2016 01:06 
B  6/16/2016 01:03 
B  12/30/2015 23:04:25 

Как извлечь часов в отдельный столбец? Желаемый результат:

cust  timestamp   hours 
A  5/31/2016 1:03:12  1 
A  05/25/2016 01:06  1 
B  6/16/2016 9:03   9 
B  12/30/2015 23:04:25 23 

Я предпочитаю ответ с tidyverse и мутировать, но моя попытка не удается правильно извлечь часы:

df %>% mutate(hours=strptime(timestamp, '%H') %>% as.character()) 

# A tibble: 4 × 3 
    cust   timestamp    hours 
    <chr>    <chr>    <chr> 
1  A 5/31/2016 1:03:12 2016-10-31 05:00:00 
2  A 05/25/2016 01:06 2016-10-31 05:00:00 
3  B 6/16/2016 01:03 2016-10-31 06:00:00 
4  B 12/30/2015 23:04:25 2016-10-31 12:00:00 
+1

Вы пробовали преобразования «метку» в дата-время, прежде чем пытаться извлечь часы? Кажется, что 'as.POSIXct (df $ timestamp, format ="% m /% d /% Y% H:% M ")' может сделать трюк для вас, если вам не нужны секунды. – aosmith

ответ

4

Попробуйте это:

library(lubridate) 
df <- data.frame(cust=c('A','A','B','B'), timestamp=c('5/31/2016 1:03:12', '05/25/2016 01:06', 
                 '6/16/2016 09:03', '12/30/2015 23:04:25')) 
df %>% mutate(hours=hour(strptime(timestamp, '%m/%d/%Y %H:%M')) %>% as.character()) 

cust   timestamp hours 
1 A 5/31/2016 1:03:12  1 
2 A 05/25/2016 01:06  1 
3 B 6/16/2016 09:03  9 
4 B 12/30/2015 23:04:25 23 
+0

Красивые, @sandipan! Для преобразования часов в целые числа также работает: df%>% mutate (hours = hour (strptime (timestamp, '% m /% d /% Y% H:% M'))%>% as.integer()) – Irakli

+0

Спасибо pal @Irakli –

1

Вот решение, которое присоединяет 00 за секунды, когда они отсутствуют , затем преобразуется в дату с использованием lubridate и извлекает часы, используя format. Обратите внимание, что если вы не хотите, чтобы 00:00 в конце часов, вы можете просто удалить их из выходного формата в format:

df %>% 
    mutate(
    cleanTime = ifelse(grepl(":[0-9][0-9]:", timestamp) 
         , timestamp 
         , paste0(timestamp, ":00")) %>% mdy_hms 
    , hour = format(cleanTime, "%H:00:00") 
    ) 

возвращается:

cust   timestamp   cleanTime  hour 
    <chr>    <chr>    <dttm> <chr> 
1  A 5/31/2016 1:03:12 2016-05-31 01:03:12 01:00:00 
2  A 05/25/2016 01:06 2016-05-25 01:06:00 01:00:00 
3  B 6/16/2016 01:03 2016-06-16 01:03:00 01:00:00 
4  B 12/30/2015 23:04:25 2015-12-30 23:04:25 23:00:00 
1

Вашей меткой является символом string(), вам нужно форматировать как дату (например, as.Date), прежде чем вы сможете начать использовать такие функции, как strptime.

Вам нужно будет выполнить некоторые строковые манипуляции, чтобы иметь правильно отформатированные данные, прежде чем вы сможете преобразовать их в даты. Подготовьте ноль к месяцам с помощью одной цифры и добавьте :00 в часы с отсутствующими секундами. Используйте strsplit() и другие функции регулярных выражений. Впоследствии сделайте as.Date(df$timestamp,format = '%m/%d/%Y %H:%M:%S'), тогда вы сможете использовать strptime, чтобы извлечь часы.