-1

I have a dataset with date and time variables. I created a new variable (mutated from time) and called it "time.of.day". I would like to assign different labels (4 actually) conditioned by the time period. I was trying the following:

levels(df$time.of.day) <- list(
    label_1 = df$time.of.day[df$time >= "07:00:00" & df$time <= "10:00:00"],
    label_2 = df$time.of.day[df$time >= "10:00:00" & df$time <= "16:00:00"],
    label_3 = df$time.of.day[df$time >= "16:00:00" & df$time <= "19:00:00"],
    label_4 = df$time.of.day[df$time >= "19:00:00" & df$time <= "23:59:59"]
    )

but nothing happens and I get no errors or warnings.

Here's a sample of the mentioned columns:

             date     time time.of.day
1      2014-03-21 09:20:08    09:20:08
2      2014-03-21 10:05:22    10:05:22
3      2014-03-26 05:34:04    05:34:04
4      2014-03-26 09:35:05    09:35:05
5      2014-03-27 01:45:03    01:45:03
6      2014-03-27 02:45:27    02:45:27
7      2014-03-27 14:46:26    14:46:26
8      2014-03-28 04:03:30    04:03:30

To make it easier for future users here's the code to generate the data frame above:

df <- data.frame(
date = c("2014-03-21", "2014-03-21", "2014-03-26", "2014-03-26", "2014-03-27", "2014-03-27", "2014-03-27", "2014-03-28"),
time = c("09:20:08", "10:05:22", "05:34:04", "09:35:05", "01:45:03", "02:45:27", "14:46:26", "04:03:30"),
time.of.day = c("09:20:08", "10:05:22", "05:34:04", "09:35:05", "01:45:03", "02:45:27", "14:46:26", "04:03:30")

)

P.S.: I have done this in previous work with unique, grep & character strings and it works.

Could you please help? Thanks

divibisan
  • 8,631
  • 11
  • 31
  • 46
user10853
  • 266
  • 1
  • 3
  • 17

2 Answers2

1

Ok so I used "[" to solve this. But I am still curious as to why it didn't work with levels & list?

df$time.of.day[df$time >= "00:00:00" & df$time <= "07:00:00"] <- "morning"
df$time.of.day[df$time >= "07:00:00" & df$time <= "10:00:00"] <- "home2work"
df$time.of.day[df$time >= "10:00:00" & df$time <= "16:00:00"] <- "mid_day"
df$time.of.day[df$time >= "16:00:00" & df$time <= "19:00:00"] <- "work2home"
df$time.of.day[df$time >= "19:00:00" & df$time <= "23:59:59"] <- "night"
user10853
  • 266
  • 1
  • 3
  • 17
0

Other option would be:

library(chron)
indx <- c('00:00:00', '07:00:00', '10:00:00', '16:00:00',
                  '19:00:00', '23:59:59')
indx2 <- c('morning', 'home2work', 'mid_day', 'work2home', 'night')
h1 <- chron(times=df$time)
br <- chron(times=indx)
df$time.of.day <-  cut(h1, br, labels=indx2)
df$time.of.day
#[1] home2work mid_day   morning   home2work morning   morning   mid_day  
#[8] morning  
#Levels: morning home2work mid_day work2home night

Or you could do:

indx3 <- max.col(t(Vectorize(function(x) x>=indx[-length(indx)] & 
                                 x<= indx[-1])(df$time)), 'first')
indx2[indx3]
# [1] "home2work" "mid_day"   "morning"   "home2work" "morning"   "morning"  
# [7] "mid_day"   "morning"  

data

df <-  structure(list(date = c("2014-03-21", "2014-03-21", "2014-03-26", 
"2014-03-26", "2014-03-27", "2014-03-27", "2014-03-27", "2014-03-28"
), time = c("09:20:08", "10:05:22", "05:34:04", "09:35:05", "01:45:03", 
"02:45:27", "14:46:26", "04:03:30"), time.of.day = c("09:20:08", 
"10:05:22", "05:34:04", "09:35:05", "01:45:03", "02:45:27", "14:46:26", 
"04:03:30")), .Names = c("date", "time", "time.of.day"), class = "data.frame", 
row.names = c("1", "2", "3", "4", "5", "6", "7", "8"))
akrun
  • 674,427
  • 24
  • 381
  • 486