I have in my dataset dates and times. They are in as.POSIXct format.
I want to change dates/times to NA, if the time is 00:00:00.
The name of the column is for example Data$Operation
This date/time is correct: 2015-01-01 11:45:00
This date/time has to change to NA: 2015-01-02 00:00:00
How can I do that?
Using x as test data replace any component for which the format using %T is as shown.
# test input
x <- as.POSIXct(c("2015-01-01 11:45:00", "2015-01-01 00:00:00"))
replace(x, format(x, "%T") == "00:00:00", NA)
## [1] "2015-01-01 11:45:00 EST" NA
Related
This question already has answers here:
Convert date-time string to class Date
(4 answers)
Closed 3 years ago.
I have date&time stamp as a character variable
"2018-12-13 11:00:01 EST" "2018-10-23 22:00:01 EDT" "2018-11-03 14:15:00 EDT" "2018-10-04 19:30:00 EDT" "2018-11-10 17:15:31 EST" "2018-10-05 13:30:00 EDT"
How can I strip the time from this character vector?
PS: Can someone please help. I have tried using strptime but I am getting NA values as a result
It's a bit unclear whether you want the date or time but if you want the date then as.Date ignores any junk after the date so:
x <- c("2018-12-13 11:00:01 EST", "2018-10-23 22:00:01 EDT")
as.Date(x)
## [1] "2018-12-13" "2018-10-23"
would be sufficient to get a Date vector from the input vector x. No packages are used.
If you want the time then:
read.table(text = x, as.is = TRUE)[[2]]
## [1] "11:00:01" "22:00:01"
If you want a data frame with each part in a separate column then:
read.table(text = x, as.is = TRUE, col.names = c("date", "time", "tz"))
## date time tz
## 1 2018-12-13 11:00:01 EST
## 2 2018-10-23 22:00:01 EDT
I think the OP wants to extract the time from date-time variable (going by the title of the question).
x <- "2018-12-13 11:00:01 EST"
as.character(strptime(x, "%Y-%m-%d %H:%M:%S"), "%H:%M:%S")
[1] "11:00:01"
Another option:
library(lubridate)
format(ymd_hms(x, tz = "EST"), "%H:%M:%S")
[1] "11:00:01"
The package lubridate makes everything like this easy:
library(lubridate)
x <- "2018-12-13 11:00:01 EST"
as_date(ymd_hms(x))
You can use the as.Date function and specify the format
> as.Date("2018-12-13 11:00:01 EST", format="%Y-%m-%d")
[1] "2018-12-13"
If all values are in a vector:
x = c("2018-12-13 11:00:01 EST", "2018-10-23 22:00:01 EDT",
"2018-11-03 14:15:00 EDT", "2018-10-04 19:30:00 EDT",
"2018-11-10 17:15:31 EST", "2018-10-05 13:30:00 EDT")
> as.Date(x, format="%Y-%m-%d")
[1] "2018-12-13" "2018-10-23" "2018-11-03" "2018-10-04" "2018-11-10"
[6] "2018-10-05"
I have downloaded the 2015-2017 sunset/sunrise data from the Navy and I am trying to format it into dates and time to further use with other data I have. This is how my data set looks in R.
I have managed to convert the date into the right R data format. Yet, I still can't convert my rise/set column data from a number/integer format to a time data (as hh:mm).
Based on one internet source, I wrote the following codes:
Sun2015$Srise<- format(strptime(Sun2015$Rise, format="%H:%M"))
However this gives NA in my data
OR
Sun2015$Srise<-str_pad(Sun2015$Rise, 4, pad="0")
Sun2015$Srise<-hour(hm(Sun2015$Srise))
Yet, I received the following error:
Warning message: In .parse_hms(..., order = "HM", quiet = quiet) :
Some strings failed to parse.
Is there a better way to convert the columns into the right time format so that I can merge the date and time columns into date-time columns for sunset and sunrise?
Thank you in advance for your help.
You can convert your military time to 2400 time strings using sprint("%04d", data) and go from there. For example, with the first 5 lines of your data:
# Sample of your data
Day <- c("1/1/2015", "1/2/2015", "1/3/2015", "1/4/2015", "1/5/2015")
Rise <- c(652,652,652,653,653)
Set <- c(1755,1756,1756,1757,1757)
sun2015 <- data.frame(Day, Rise, Set)
# Convert to 2400 style strings with leading zeroes where necessary
sun2015$Rise <- sprintf("%04d", sun2015$Rise)
sun2015$Set <- sprintf("%04d", sun2015$Set)
# Merge with your date
sun2015$day_rise <- as.POSIXct(paste0(sun2015$Day, " ",sun2015$Rise), format = "%m/%d/%Y %H%M", origin = "1970-01-01", tz = "UTC")
sun2015$day_set <- as.POSIXct(paste0(sun2015$Day, " ",sun2015$Set), format = "%m/%d/%Y %H%M", origin = "1970-01-01", tz = "UTC")
> sun2015$day_rise
[1] "2015-01-01 06:52:00 UTC" "2015-01-02 06:52:00 UTC" "2015-01-03 06:52:00 UTC" "2015-01-04 06:53:00 UTC"
[5] "2015-01-05 06:53:00 UTC"
> sun2015$day_set
[1] "2015-01-01 17:55:00 UTC" "2015-01-02 17:56:00 UTC" "2015-01-03 17:56:00 UTC" "2015-01-04 17:57:00 UTC"
[5] "2015-01-05 17:57:00 UTC"
You can adjust to the appropriate time zone if necessary.
I want to get a time sequence without using dates in R. I googled it but didn't find anything . I have one approach of doing this but that is too with dates.
a <- seq(from=as.POSIXct("2012-01-01 00:00:00", tz="UTC"),
to=as.POSIXct("2012-01-01 05:00:00", tz="UTC"), by="hour")
a <- strftime(a, format="%H:%M:%S", tz = "UTC")
a <- times(a)
a
[1] 00:00:00 01:00:00 02:00:00 03:00:00 04:00:00 05:00:00
I just want to know is there exist any approach that produce a time sequence (w/o using dates)
The "times" class of chron can represent times below 24:00:00 without dates:
library(chron)
times(0:5/24)
## [1] 00:00:00 01:00:00 02:00:00 03:00:00 04:00:00 05:00:00
Maybe
substr(as.character(a),12,19)
OR
sapply(strsplit(as.character(a)," "), "[[", 2)
Im have a time stamp column that I am converting into a POSIXct. The problem is that there are two different formats in the same column, so if I use the more common conversion the other gets converted into NA.
MC$Date
12/1/15 22:00
12/1/15 23:00
12/2/15
12/2/15 1:00
12/2/15 2:00
I use the following code to convert to a POSIXct:
MC$Date <- as.POSIXct(MC$Date, tz='MST', format = '%m/%d/%Y %H:%M')
The results:
MC$Date
15-12-01 22:00:00
15-12-01 23:00:00
NA
15-12-02 01:00:00
15-12-02 02:00:00
I have tried using a logic vector to identify the issue then correct it but can't find an easy solution.
The lubridate package was designed to deal with situations like this.
dt <- c(
"12/1/15 22:00",
"12/1/15 23:00",
"12/2/15",
"12/2/15 1:00",
"12/2/15 2:00"
)
dt
[1] "12/1/15 22:00" "12/1/15 23:00" "12/2/15" "12/2/15 1:00" "12/2/15 2:00"
lubridate::mdy_hm(dt, truncated = 2)
[1] "2015-12-01 22:00:00 UTC" "2015-12-01 23:00:00 UTC" "2015-12-02 00:00:00 UTC"
[4] "2015-12-02 01:00:00 UTC" "2015-12-02 02:00:00 UTC"
The truncated parameter indicates how many formats can be missing.
You may add the tz parameter to specify which time zone to parse the date with if UTC is not suitable.
I think the logic vector approach could work. Maybe in tandem with an temporary vector for holding the parsed dates without clobbering the unparsed ones. Something like this:
dates <- as.POSIXct(MC$Date, tz='MST', format = '%m/%d/%Y %H:%M')
dates[is.na(dates)] <- as.POSIXct(MC[is.na(dates),], tz='MST', format = '%m/%d/%Y')
MC$Date <- dates
Since all of your datetimes are separated with a space between date and time, you could use strsplit to extract only the date part.
extractDate <- function(x){ strsplit(x, split = " " )[[1]][1] }
MC$Date <- sapply( MC$Date, extractDate )
Then go ahead and convert any way you like, without worrying about the time part getting in the way.
For an array of POSIXct values:
2015-01-01 10:04
2015-01-01 10:05
2015-01-01 10:10
2015-01-01 10:20
2015-01-01 10:30
2015-01-02 11:04
2015-01-02 11:30
..
I'd like to change the date 2015-01-02 to 2015-02-03. How can I do that?
My first attempt was to somehow separately extract the date and timestamp portions of the POSIXct vector, replace the date as you wanted, and then roll it back up to a new POSIXct vector. However, this seemed to lead nowhere fast, so then I tried just converting the POSIXct vector to character, and then using gsub() to make the date replacement. After this, the character vector can easily be converted back to a POSIXct vector.
y <- as.POSIXct(c("2015-01-01 10:30", "2015-01-02 11:04", "2015-01-02 11:30"),
format="%Y-%m-%d %H:%M")
y.replace <- gsub("2015-01-02", "2015-02-03", as.character(y))
result <- as.POSIXct(y.replace, format="%Y-%m-%d %H:%M:%S")
> result
[1] "2015-01-01 10:30:00 MYT" "2015-02-03 11:04:00 MYT"
[3] "2015-02-03 11:30:00 MYT"