Converting character variable in date format - r

I'd like to convert my variable "birthdate" from a character class to dates. They're actually written like that "dd/mm/yyyy". I tried to use the function as.Date but I obtained something wrong :
x$age <- as.Date(x$birhtdate)
R doesn't read the character string correctly. For example 21/12/1948 becomes 0021/12/19
I am a bit lost, I also tried to use the function format but without success.
Thank for your help !

You can use the R package lubridate to explicitly use specific ordering of day and month:
x <- data.frame(birhtdate = "21/12/1948")
x$birhtdate <- lubridate::parse_date_time(x$birhtdate, orders = "dmy")
x
#> birhtdate
#> 1 1948-12-21
Created on 2023-01-04 by the reprex package (v2.0.1)

base R answer:
Yes, you need to provide R with the format, there are so much different possibilities like '-' or a space or different order mm/dd/yyyy
So:
as.Date('21/12/1948', format = '%d/%m/%Y')
will work.
Output:
[1] "1948-12-21"

Related

R Converting Datetime to an actual string

I am trying to convert a date time to an actual string. But when I use as.character(x) then it returns a value that I can't convert to a date or time.
for instance:
When I extract the data from a particular cell in the dataframe df it returns:
> df[1,6]
# A tibble: 1 x 1
`PLS FFM`
<dttm>
1 2019-12-14 06:47:00
When I try to convert it to a string it returns:
> (as.character(df[1,6]))
[1] "1576306020"
But when I try to convert the string or the datetime () to a date format it returns:
> as.Date(as.character(df[1,6]))
Error in charToDate(x) :
character string is not in a standard unambiguous format
I all ready searched on the internet for hours trying to find a solution, but it's seems that I either doings something wrong or I am honestly really stupid.
Can somebody help me out!?
Thanks,
JOP
Answer thanks to Ronak Shah!
After Ronak Suggested that I should convert the whole vector with format I was able to convert the formatted vector to a Date + time that I can use in my script where I make a lot of calculations with the time. I Used:
df$'PLS FFM' <- format(df$'PLS FFM')
df$'PLS FFM' <- as.POSIXCT(df$'PLS FFM')
Thanks to Ronak
Since df[1,6] is still a tibble using as.character doesn't work on it. You need to pass a vector to as.character which can be done with
as.character(df$`PLS FFM`)
#OR
#as.character(df[["PLS FFM"]])
We can also use format
format(df$`PLS FFM`)
If you need a specific value from the dataframe, use
as.character(df$`PLS FFM`[1])

R: why a '%b.%Y' date class is not "Date"?

Sometimes I work with data like this:
sep-2018
From date like this:
Sys.Date()
[1] "2018-09-21"
To have this result, I generally use:
format(Sys.Date(),'%b-%Y')
But its class is not a date:
class(format(Sys.Date(),'%b-%Y'))
[1] "character"
Why it's not a date? Is it possible to have it with class() = date, and how?
Also an external library like zoo have the same thing.
library(zoo)
> class(format(as.yearmon(format(Sys.Date()), "%Y-%m-%d"), "%b.%Y"))
[1] "character"
Also using "%m.%Y" seems to generate the same thing, but it does not creates (for example) ordering issue.
The format command takes the date and outputs a printable string based on the format you provide. To quote the documentation:
An object of similar structure to x containing character representations of the
elements of the first argument x in a common format, and in the current
locale's encoding.
Also, a Date variable is stored as a numeric type internally (number of days since 1970-01-01)
dput(Sys.Date())
#structure(17795, class = "Date")
structure(0, class = "Date")
#[1] "1970-01-01"
So to pinpoint the date, you need day, month and year fields. If you don't have all three, it will probably return NA or an error. Similarly for time classes. If you don't have the data then you can just use some dummy values, and use format to print only the fields you want.
As Rohit says, format doesn't outputs a Date object, but a string in the format of your choice.
To get a Date object from a string like "sep-2018" you could use readr::parse_date().
(my_date <- readr::parse_date("sep-2018", format = '%b-%Y'))
#[1] "2018-09-01"
class(my_date)
#[1] "Date"

How to lag dates in form of strings in R

The following vector of Dates is given in form of a string sequence:
d <- c("01/09/1991","01/10/1991","01/11/1991","01/12/1991")
I would like to exemplary lag this vector by 1 month, that means to produce the following structure:
d <- c("01/08/1991","01/09/1991","01/10/1991","01/11/1991")
My data is much larger and I must impose higher lags as well, but this seems to be the basis I need to know.
By doing this, I would like to have the same format in the end again:("%d/%m/%Y). How can this be done in R? I found a couple of packages (e.g. lubridate), but I always have to convert between formats (strings, dates and more) so it's a bit messy and seems prone to mistake.
edit: some more info on why I want to do this: I am using this vector as rownames of a matrix, so I would prefer a solution where the final outcome is a string vector again.
This does not use any packages. We convert to "POSIXlt" class, subtract one from the month component and convert back:
fmt <- "%d/%m/%Y"
lt <- as.POSIXlt(d, format = fmt)
lt$mon <- lt$mon - 1
format(lt, format = fmt)
## [1] "01/08/1991" "01/09/1991" "01/10/1991" "01/11/1991"
My solution uses lubridatebut it does return what you want in the specified format:
require(lubridate)
d <- c("01/09/1991","01/10/1991","01/11/1991","01/12/1991")
format(as.Date(d,format="%d/%m/%Y")-months(1),'%d/%m/%Y')
[1] "01/08/1991" "01/09/1991" "01/10/1991" "01/11/1991"
You can then change the lag and (if you want) the output (which is this part : '%d/%m/%Y') by specifying what you want.

Using R, How to Convert a Factor into a Date without losing the year?

When I read in a data file using R, a Date variable is a Factor.
For example, let epc hold the data set. Then if we look at the structure of the first date, we get
str(epc$Date[1])
Factor w/ 1 level "16/12/2006": 1
If you were to convert this to a character, as.character(epc$Date[1]), you'd get exactly the same thing: "16/12/2006"
No matter what I've tried, I can't convert this type of object into a valid date.
if the date is "16/12/2006" (which I'm assuming is Dec. 16th, 2006), then as.Date(epc_full$Date[1]) gives "0016-12-20" -- the full year is lost.
I've tried many different things, e.g., first converting the date into a character, trying different versions of as.Date(), etc., but I keep getting exactly the same result when the input is "16/12/2006"
What's the trick here?
So first, for some reason this is being read in as a factor with a level that is labeled "16/12/2006". You are converting this to a character, so I'll start there.
There are a number of ways to do this, but I think the easiest is to use the lubridate package.
#Install package
install.packages("lubridate")
library(lubridate)
yourTextDate <- "16/12/2006"
yourDate <- dmy(yourTextDate)
yourDate
If you strictly want a Date class, then:
as.Date(s, format='%d/%m/%Y')
## [1] "2006-12-16"
class(.Last.value)
## [1] "Date"
So you can convert the entire column of dates with:
as.Date(epc$Date, format='%d/%m/%Y')
This should work whether it is a character or factor.
lubridate works well as well, but if you're sticking with base R, this works well too.

Character to date in R

One of the columns in my data frame is a character which has the following format (an example):
2013-02-05 08:00:00
Some of the rows are NULL in this column. I want to change the class to date format but I am getting NA for all rows.
Could you please tell me what should I do to make it work?
You should install Hadley Wickham's lubridate package, and use:
> ymd_hms("2013-02-05 08:00:00")
The package includes many other functions that'll help you (safely) manipulate datetime and interval objects.
Based on your comment, assuming your data frame is DF, and your date column (as character) DATE.STR, I would do the following:
DF$DATE=as.Date(DF$DATE.STR)
Of course, using lubridate would give you more options, but I think you can use base R for this.

Resources