2

I have a column in R on my dataset with values that have been converted into what I believe is a time decimal fraction based on days. I have been using this site as a reference: http://www.calculatorsoup.com/calculators/time/decimal-to-time-calculator.php

Which converting 0.3408565 days corresponds to the time of 8:10:50 by doing the following:

0.3408565 * 24 hours/day = 8.180555544 = 8 hours

0.180555544 * 60 minutes = 10.83333264 = 10 minutes

0.83333264 * 60 seconds = 49.9999584 = 50 seconds

As you can see it is extracting the remainder and doing further multiplication, however I'm not sure how I could implement the process within R. I want to convert all the values in my column using this so I can replace 0.3408565, 0.3864468, 0.4400231 etc with their actual time counterparts 8:10:50, 09:16:29, 10:33:38 respectively. This seems to be how it is done in Excel too.

I tried writing my own function which in English does:

convertTime <- function(x)
{
x * 60 = Hour
x2 * 24 = Min
x3 * 24 = Sec

hourChar <- as.character(Hour)
minChar <- as.character(Min)
secChar <- as.character(Sec)
paste(hourChar, minChar, secChar, sep=":")
}

With x being 0.3408565, but of course this doesn't extract the remainder. I might be seriously overcomplicating it, but I want to loop through all values in the column using each value as input to convert.

Lastly, I have looked at packages such as 'lubridate' but cannot find anything that is relevant to my problem.

I also browsed here for my specific situation but couldn't find anything really relevant to my problem. Is there any package or solution that could help me?

EDIT: I want to say both answers work perfectly for anyone else having this kind of problem, thank you to you both!

KieranLowe
  • 81
  • 1
  • 10

2 Answers2

3

Try times in chron which represents times as fractions of a day:

library(chron)
format(times(0.3408565))
## [1] "08:10:50"

If you have something like x = 3.3408565 days then this can be formatted as:

x <- 3.3408565
paste(x %/% 1, times(x %% 1))
## [1] "3 08:10:50"

Regarding the subject of the question it is not clear what an "actual time in R" means but time intervals can be expressed as "difftime" objects so if you want to convert x to a "difftime" class R object then:

as.difftime(x, units = "days")
## Time difference of 3.340857 days

or if you want to subtract x from the current date/time:

Sys.time() - as.difftime(x, units = "days")
## [1] "2017-01-27 05:00:22 EST"

There is also some information that may be relevant in the R Help Desk column of R News 4/1 including information on converting Excel date/times in R -- https://www.r-project.org/doc/Rnews/Rnews_2004-1.pdf

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
2

Here's a custom function

convertTime <- function(x){
    Hour = (x * 24) %% 24 #For x>1, only the value after decimal will be considered
    Minutes = (Hour %% 1) * 60
    Seconds = (Minutes %% 1) * 60

    hrs = ifelse (Hour < 10, paste("0",floor(Hour),sep = ""), as.character(floor(Hour)))
    mins = ifelse (Minutes < 10, paste("0",floor(Minutes),sep = ""), as.character(floor(Minutes)))    
    secs = ifelse (Seconds < 10, paste("0",round(Seconds,0),sep = ""), as.character(round(Seconds,0)))

    return(paste(hrs, mins, secs, sep = ":"))
}

USAGE

a = seq(0,1,0.2)
convertTime(a)
#[1] "00:00:00" "04:48:00" "09:36:00" "14:24:00" "19:12:00" "00:00:00"

b = 0.3408565
convertTime(b)
# [1] "08:10:50"
d.b
  • 32,245
  • 6
  • 36
  • 77
  • I have just tried this solution and it works perfectly for my situation, thank you ever so much! By any chance would you be aware of how a date can also be converted without asking another question for it? Again I have a date (41641) which I can convert to 02/01/2014 which I think 41641 is the number of days since 01/01/1900? – KieranLowe Jan 30 '17 at 23:11
  • `as.Date(41641, origin = "1900-01-01")` – d.b Jan 30 '17 at 23:15
  • 1
    This is perfect thank you so much for your help, I just have to convert it to UK time which I will figure out how to do! Again thank you so much! – KieranLowe Jan 30 '17 at 23:21
  • Great answer, but it's not rounding time to the next minute at seconds = 60. Any ideas? For example, I get this ->12:33:60 – Nate Mar 07 '22 at 20:45