2016-10-31 1 views
1

Mon dataframe a horodatage avec et sans secondes, et une utilisation aléatoire de 0 devant des mois et des heures, soit 01 ou 1R: extrait heure de l'horodatage à format variable

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 

Comment extraire heures dans un colonne séparée? La sortie souhaitée:

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 

Je préfère la réponse avec tidyverse et muter, mais ma tentative ne parvient pas à extraire heures correctement:

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

Avez-vous essayé de convertir « horodatage » à une date-heure avant d'essayer d'extraire heures? On dirait que 'as.POSIXct (df $ timestamp, format ="% m /% d /% Y% H:% M ")' pourrait faire l'affaire pour vous si vous n'avez pas besoin des secondes. – aosmith

Répondre

4

Essayez ceci:

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

Beautiful, @sandipan! Pour convertir des heures en entiers, fonctionne aussi: df%>% mute (heures = heure (strptime (horodatage, '% m /% d /% Y% H:% M'))%>% as.integer()) – Irakli

+0

Merci à pal @Irakli –

1

Voici une solution qui ajoute 00 pour les secondes quand ils manquent , puis convertit à une date en utilisant lubridate et extrait les heures en utilisant format. Remarque, si vous ne voulez pas le 00:00 à la fin des heures, vous pouvez simplement les éliminer du format de sortie format:

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

retours:

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

Votre horodatage est un caractère string(), vous devez formater est comme une date (avec as.Date par exemple) avant de pouvoir commencer à utiliser des fonctions comme strptime.

Vous allez devoir passer par certaines manipulations de chaînes pour avoir des données correctement formatées avant de pouvoir les convertir en dates. Préfixez un zéro à plusieurs mois avec un seul chiffre et ajoutez :00 aux heures manquantes. Utilisez strsplit() et d'autres fonctions regex. Ensuite, faites as.Date(df$timestamp,format = '%m/%d/%Y %H:%M:%S'), puis vous pourrez utiliser strptime pour extraire les heures.