问题
This question already has an answer here:
- Convert a decimal number to HH:MM 3 answers
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!
回答1:
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"
回答2:
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
来源:https://stackoverflow.com/questions/41941523/converting-a-time-decimal-fraction-representing-days-to-its-actual-time-in-r