1

Some sample values :

12/01/2011 11:49    
18-01-2011 9:50:45

I want the output as:

11   
09

The class of the datetime column is factor in my original dataframe.

Psidom
  • 209,562
  • 33
  • 339
  • 356
kpratihast
  • 842
  • 1
  • 10
  • 23

2 Answers2

2

You can do this easily with the lubridate package. As pointed out by @alistaire, the default solution does not parse correctly all the information (minutes and seconds) since the formats are inconsistent (one has seconds and the other not). Fortunately, the truncated parameter is here for that. We can set it to 1 since one element is missing.

If truncated parameter is non-zero ymd_hms functions also check for truncated formats.

library(lubridate)

hour(dmy_hms(c("12/01/2011 11:49", "18-01-2011 9:50:45"), truncated = 1))

[1] 11  9

Or even better using pipeline notation %>% from the magrittr package -- love this name.

library(lubridate)    
library(magrittr)

c("12/01/2011 11:49", "18-01-2011 9:50:45") %>%
  dmy_hms(truncated = 1) %>%
  hour()

[1] 11  9
Romain
  • 19,910
  • 6
  • 56
  • 65
  • Thanks for the reminder. Post corrected to mention magrittr. – Romain Aug 28 '16 at 15:43
  • They're not both dmy_hms, so it's actually parsing the minutes incorrectly if you look at the intermediate product. If you use `parse_date_time`, you can pass multiple orders, e.g. `lubridate::parse_date_time(datetimes, c('dmy hms', 'dmy hm'))` – alistaire Aug 28 '16 at 16:36
  • [Docs](http://stackoverflow.com/documentation/r/1157/date-and-time/7018/parsing-dates-and-datetimes-from-strings-with-lubridate#t=201608281638168797469) for the above – alistaire Aug 28 '16 at 16:42
  • Thanks, I have updated my answer to take your remark into account. – Romain Aug 28 '16 at 18:33
0

One option is to use sub with regex:

dt <- c("12/01/2011 11:49", "18-01-2011 9:50:45")

sub(".*\\s(\\d{1,2}):.*", "\\1", as.character(dt))
# [1] "11" "9" 

Or str_extract from stringr:

str_extract(as.character(dt), "(?<=\\s)(\\d{1,2})(?=:)")
# [1] "11" "9" 
Psidom
  • 209,562
  • 33
  • 339
  • 356