4

I have a column representing time in a data frame in R.

when I call the str() function on the column it says something like this

>str(df2$Time)
 Factor w/ 1441 levels "","00:01","00:02","00:03",..: 1086 1096 1111 and so on

The thing is I want to conver this column into string type such that if the time is less than 12:00, it should get modified to the string "moring" , if time is between 12:00 and 6:00 , it is "daylight" and so on.

The first step I thought was to convert this vector to time type of column of data frame, so I used chron function.

I typed the following command,

>df2$Time<-chron(times=df2$Time,format=c('h:m'))
 Error in convert.times(times., fmt) : format h:m may be incorrect
 In addition: Warning message:
In is.na(out$s) : is.na() applied to non-(list or vector) of type 'NULL"

so I guessed I should have added second parameter in format so I tried the following :

df2$Time<-chron(time=df2$Time,format=c('h:m:s'))

But still got the same error

I know this is just the first step, may be my approach too is wrong. Can anyone suggest me how to convert these time data cells to morning, evening , night etc.

Any help is much appreciated.

plannapus
  • 18,529
  • 4
  • 72
  • 94
apTNow
  • 805
  • 1
  • 9
  • 20
  • `df2$Time` is of type factor with hour:minute values like `06:00`. Use `df2$Time <- ifelse(as.numeric(sub("(\\d{1,2}):.*", "\\1", df2$Time)) < 6, "night", "day")` to exchange hour values < 6 with `night` and other values with `day`. – lukeA Feb 18 '14 at 09:23
  • @lukeA that's a nice solution, you should add it as an answer. – plannapus Feb 18 '14 at 09:26

3 Answers3

4

The same thing with lubridate (sorry Joran, i like this package), and functions hour and hm:

Time <- hour(hm("13:24","19:32","3:45","08:25", "21:45", "11:13", "00:00"))
your_breaks <- hour(hm("00:00", "6:00", "12:00", "18:00", "23:59"))
your_labels <- c("Night", "Morning", "Afternoon", "Evening")
cut(x=Time, breaks=your_breaks, labels=your_labels, include.lowest=TRUE)

[1] Afternoon Evening   Night     Morning   Evening   Morning   Night
Victorp
  • 13,636
  • 2
  • 51
  • 55
4

Use chron's "times" class and cut:

library(chron)

# data in reproducible form
df2 <- data.frame(Times = c("00:01","12:02","19:03"))

df2$Times <- times(paste0(df2$Times, ":00")) # append a chron "times" class column
breaks <- c(0, 12, 18, 24) / 24 # times are internally fractions of a day
labels <- c("morning", "daylight", "evening")
df2$ind <- cut(df2$Times, breaks, labels, include.lowest = TRUE)

which gives:

> df2
     Times      ind
1 00:01:00  morning
2 12:02:00 daylight
3 19:03:00  evening

Next time please supply your data in reproducible form.

REVISED Minor simplification and fixed typo.

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • sorry but I am new here. What exactly does reproducible form mean? – apTNow Feb 24 '14 at 08:07
  • 1
    It means it is self contained and in a form that R can directly read without manual work. i.e. it should be possible to copy the data and code to the clipboard from your post and then just paste it into an R session to run it. See and the `dput` command and http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – G. Grothendieck Feb 24 '14 at 12:39
  • Typo. Have fixed. – G. Grothendieck Sep 18 '16 at 11:44
1

First some reproducible example:

time <- expand.grid(0:23,0:59)
time <- apply(time,1,function(x)sprintf("%02i:%02i",x[1],x[2]))

One way to go is to paste in front of your hour data some fake date, so that you can parse your time data as POSIXct and then use cut to sort them:

time <- strptime(paste("01/01/01",time),"%y/%m/%d %H:%M")

cut(time,
    breaks= as.POSIXct(paste("2001-01-01",
                       c("00:00:00", "12:00:00", "18:00:00", "23:59:59"))),
    labels=c('morning','afternoon','night'))
plannapus
  • 18,529
  • 4
  • 72
  • 94
  • What will the above command do? I mean how will it partition? I want to part as between 8 pm to 6 am = night , 6 am to 8 am and 5:30 pm to 8:00 pm as twighlight and 8 am to 5:30 pm as daylight. What modifications should I perform in the above command. – apTNow Feb 18 '14 at 10:21
  • 1
    The breaks are conveniently given in the argument `breaks`. So you will have to modify it the following way: `cut(time, breaks= as.POSIXct(paste("2001-01-01",c("00:00:00", "06:00:00", "08:00:00",17:30:00","20:00:00","23:59:59"))),labels=c('night','twilight','daylight','twilight','night'))` – plannapus Feb 18 '14 at 10:26
  • I did it, but got a warning : duplicated levels in factors are deprecated – apTNow Feb 18 '14 at 10:31
  • That happens if you start your break argument with "00:00:00" and finish it with "00:00:00" as well. That s why i used "23:59:59". You can't repeat a breaking point. – plannapus Feb 18 '14 at 13:25