I'm using R Studio. When I try to convert the date and time format using as.Date or as.Time I'm getting NA as the result. I also tried to set the Locale as it has been recommended in some of the problems in SO, that's also not helping. The default class is factor after I import from the text file. I also tried to make it a character. Still the problem exists. Any help?
> x<-c("16-12-2006")
> class(x)
[1] "character"
> y<-as.Date(x)
> class(y)
[1] "Date"
> y<-as.Date(x,format="d%m%Y%")
> class(y)
[1] "Date"
> y
[1] NA
You are just misplacing the %s and missing the -s in your format string.
The format string needs to match the string characters exactly (spaces, hyphens, commas, colons, etc.). See the document: Date-time Conversion Functions to and from Character.
Try:
> y <- as.Date(x, format="%d-%m-%Y")
and it should work.
Try this:
> x <- as.POSIXct(strptime("11-09-2015", "%d-%m-%Y"))
> as.Date(x)
[1] "2015-09-10"
> x
[1] "2015-09-11 CEST"
x is a class of "POSIXct" and "POSIXt", but as.Date(x) is a class of "Date" and you can use it as x-axis in ggplot.
Related
I have a list of dates in character/string format and I need to read them as POSIXct dates.
> x <- as.POSIXct("95-11-22" , format="%y-%m-%d") #should equal myParsedDates[1]
> typeof(x)
[1] "double"
> class(x)
[1] "POSIXct" "POSIXt" #Member of POSIXct class
> myDates <- c("95-11-22", "95-11-23", "95-12-25")
> myParsedDates <- mapply(function(x){as.POSIXct(x, format="%y-%m-%d")} , myDates)
> typeof(myParsedDates[1])
[1] "double"
> class(myParsedDates[1])
[1] "numeric" #Not a member of POSIXct
> x #The class information is retained
[1] "1995-11-22 AWST"
> myParsedDates[1] #The class information is lost
95-11-22
816969600
Why, when mapply is called on the list, does the POSIXct class information get lost? How can it be retained?
This is in essence a more complicated version of the (known, documented, still sad) mis-feature of S3 class attributes dropping when concatenating vectors.
I am using as.Date() here (and a string that parses without format), but it is the same with as.POSIXct().
First, what works:
> as.Date("2022-01-16")
[1] "2022-01-16"
> as.Date("2022-01-16")
[1] "2022-01-16"
>
Second, what doesn't _because sapply constructs a vector:
> sapply(c("2022-01-16", "2022-01-17"), as.Date)
2022-01-16 2022-01-17
19008 19009
> class(sapply(c("2022-01-16", "2022-01-17"), as.Date))
[1] "numeric"
>
The actual names comes back because sapply is kind to use them as label, but the result is not longer a Date object. For completeness, same with as.POSIXct:
> as.POSIXct("2022-01-16")
[1] "2022-01-16 CST"
> class(as.POSIXct("2022-01-16"))
[1] "POSIXct" "POSIXt"
> class(sapply(c("2022-01-16", "2022-01-17"), as.POSIXct))
[1] "numeric"
>
It works via lapply and do.call():
> do.call(c, lapply(c("2022-01-16", "2022-01-17"), as.Date))
[1] "2022-01-16" "2022-01-17"
> class(do.call(c, lapply(c("2022-01-16", "2022-01-17"), as.Date)))
[1] "Date"
>
It also works if you make the objects part of a data.frame and stack the data.frame rows, and/or if you inject them into pre-allocated vectors, or ... if one simply calls vectorised:
> as.Date(c("2022-01-16", "2022-01-17"))
[1] "2022-01-16" "2022-01-17"
> class(as.Date(c("2022-01-16", "2022-01-17")))
[1] "Date"
>
which is of course not always possible.
I am working on a project that requires getting the exact second from a POSIXct object. For example, if printing out a POSIXct object named tm :
> tm
[1] "2017-07-10 09:03:32.26876 BRT"
> class(tm)
[1] "POSIXct" "POSIXt"
If I run:
> format(tm, "%S")
[1] "32"
which only prints out the decimal, instead I want "32.26876", how do I do that? Thanks for the help in advance.
You can use %OS parameter to extract fractional seconds:
tm <- as.POSIXct("2017-07-10 09:03:32.26876 BRT", format="%Y-%m-%d %H:%M:%OS")
class(tm)
# [1] "POSIXct" "POSIXt"
# set the second digits option
options(digits.secs=5)
# `strftime` or `format`:
strftime(tm, "%OS")
#[1] "32.26875"
format(tm, "%OS")
#[1] "32.26875"
From ?strftime the following is noted:
Specific to R is %OSn, which for output gives the seconds
truncated to 0 <= n <= 6 decimal places (and if %OS is not
followed by a digit, it uses the setting of
getOption("digits.secs"), or if that is unset, n = 0).
Hence we can recover up to 6 decimal places, although there seems to be some change in this information:
> tm <- as.POSIXct("2017-07-10 09:03:32.26876", tz = "BRT")
> tm
[1] "2017-07-10 09:03:32.268 BRT"
> format(tm, "%OS5")
[1] "32.26875"
> format(tm, "%OS6")
[1] "32.268759"
If you convert it to a POSIXlt, this is easy.
tm = as.POSIXct("2017-07-10 09:03:32.26876 BRT")
as.POSIXlt(tm)$sec
[1] 32.26876
I am trying to set the C locale so that when I convert character objects to dates I don't get NA values. I got this solution from this question, but it's not working for me. When I run the first commented line,
> lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
I get the following warning:
Warning message:
In readLines(outfile) :
incomplete final line found on 'tmp/Rtmp8AJy9P/Rhttpd9742ffa74dc'
[1] "C"
Then when I try to convert a character object to date, I still get an NA of class date.
> x <- "2015-02-15"
> z <- as.Date(x, "%Y-%B-%d")
> Sys.Setlocale("LC_TIME", lct)
[1] "en_US.UTF-8"
> z
[1] NA
Does anyone know what that warning means and if it could be affecting the conversion that I run later?
In
> x <- "2015-02-15"
> z <- as.Date(x, "%Y-%B-%d")
> Sys.Setlocale("LC_TIME", lct)
[1] "en_US.UTF-8"
> z
[1] NA
you have the wrong format as %B stands for the textual, unabbreviated month. Witness:
R> as.Date("2015-02-15", "%Y-%m-%d")
[1] "2015-02-15"
R> as.Date("2015-February-15", "%Y-%B-%d")
[1] "2015-02-15"
R>
so I think your locale issue may be a distraction.
I am trying to convert the string "2013-JAN-14" into a Date as follow :
sdate1 <- "2013-JAN-14"
ddate1 <- as.Date(sdate1,format="%Y-%b-%d")
ddate1
but I get :
[1] NA
What am I doing wrong ? should I install a package for this purpose (I tried installing chron) .
Works for me. The reasons it doesn't for you probably has to do with your system locale.
?as.Date has the following to say:
## This will give NA(s) in some locales; setting the C locale
## as in the commented lines will overcome this on most systems.
## lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
z <- as.Date(x, "%d%b%Y")
## Sys.setlocale("LC_TIME", lct)
Worth a try.
This can also happen if you try to convert your date of class factor into a date of class Date. You need to first convert into POSIXt otherwise as.Date doesn't know what part of your string corresponds to what.
Wrong way: direct conversion from factor to date:
a<-as.factor("24/06/2018")
b<-as.Date(a,format="%Y-%m-%d")
You will get as an output:
a
[1] 24/06/2018
Levels: 24/06/2018
class(a)
[1] "factor"
b
[1] NA
Right way, converting factor into POSIXt and then into date
a<-as.factor("24/06/2018")
abis<-strptime(a,format="%d/%m/%Y") #defining what is the original format of your date
b<-as.Date(abis,format="%Y-%m-%d") #defining what is the desired format of your date
You will get as an output:
abis
[1] "2018-06-24 AEST"
class(abis)
[1] "POSIXlt" "POSIXt"
b
[1] "2018-06-24"
class(b)
[1] "Date"
My solution below might not work for every problem that results in as.Date() returning NA's, but it does work for some, namely, when the Date variable is read in in factor format.
Simply read in the .csv with stringsAsFactors=FALSE
data <- read.csv("data.csv", stringsAsFactors = FALSE)
data$date <- as.Date(data$date)
After trying (and failing) to solve the NA problem with my system locale, this solution worked for me.
I have an integer which I want to convert to class Date. I assume I first need to convert it to a string, but how?
My attempt:
v <- 20081101
date <- as.Date(v, format("%Y%m%d"))
Error in charToDate(x) : character string is not in a standard
unambiguous format
Using paste() works, but is that really the correct way to do the conversion?
date <- as.Date(paste(v), format("%Y%m%d"))
date
[1] "2008-11-01"
class(date)
# [1] "Date"
as.character() would be the general way rather than use paste() for its side effect
> v <- 20081101
> date <- as.Date(as.character(v), format = "%Y%m%d")
> date
[1] "2008-11-01"
(I presume this is a simple example and something like this:
v <- "20081101"
isn't possible?)
Another way to get the same result:
date <- strptime(v,format="%Y%m%d")
You can use ymd from lubridate
lubridate::ymd(v)
#[1] "2008-11-01"
Or anytime::anydate
anytime::anydate(v)
#[1] "2008-11-01"