Trouble reformatting date with as.Date - r

I'm having a simple problem and I can't tell what's wrong. I'm trying to convert dates formatted "YYYY-MM-DD" to "m/d/YYYY". On my machine, this code:
x <- as.Date("2000-01-01")
x <- as.Date(x, format = "%m/%d/%Y")
print(x)
returns
"2000-01-01"
What am I missing?

as.Date() creates a date object where you tell it how to interpret the input with a format argument.
format() (or alternatively strftime()) will convert a date object to a character object in a desired format:
x <- as.Date("2000-01-01")
x
[1] "2000-01-01"
str(x)
Date[1:1], format: "2000-01-01"
y <- format(x = x,format = "%m/%d/%Y")
y
[1] "01/01/2000"
str(y)
chr "01/01/2000"
y <- strftime(x = x,format = "%m/%d/%Y")
y
[1] "01/01/2000"
str(y)
chr "01/01/2000"

Related

How to find weekday number from datetime format in R

I have a dataset that contains DateTime in (dd-mm-yy hh: mm) format. I want to find the weekday number? I have tried the weekday function, but it is showing the wrong output.
wday("13-06-21 19:32")
6
The datetime is not in the POSIXct class i.e. it is just character class. We need to convert and then apply
library(lubridate)
wday(dmy_hm("13-06-21 19:32"))
[1] 1
According to the ?wday
x- a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, or fts object.
Thus, a character input may return incorrect value
If we check the source code
> methods('wday')
[1] wday.default* wday.numeric*
> getAnywhere(wday.default)
function (x, label = FALSE, abbr = TRUE, week_start = getOption("lubridate.week.start",
7), locale = Sys.getlocale("LC_TIME"))
{
wday(as.POSIXlt(x, tz = tz(x))$wday + 1, label, abbr, locale = locale,
week_start = week_start)
}
It is calling the as.POSIXlt on a incorrect format
> as.POSIXlt("13-06-21 19:32", tz = tz("13-06-21 19:32"))
[1] "0013-06-21 19:32:00 UTC"
> as.POSIXlt("13-06-21 19:32", tz = tz("13-06-21 19:32"))$wday
[1] 5
> as.POSIXlt("13-06-21 19:32", tz = tz("13-06-21 19:32"))$wday + 1
[1] 6
You do not need extra packages such as lubridate.
Parse the date, convert to POSIXlt, and extract the weekday (and adjust for for its scale)
> D <- as.Date("13-06-21 19:32", "%d-%m-%y")
> D
[1] "2021-06-13"
>
> as.POSIXlt(D)$wday + 1 # see help(DateTimeClasses)
[1] 1
>

How to convert character and dates to dates?

My data comes from excel. The dates are in dd/mm/yyyy format:
certificado$fecha <- c("22/02/2019", "43679", "22/02/2019", "22/01/2019", "28/10/2019",
"18/09/2019")
However, R is reading some dates as mm/dd/yyyy. My code is supposed to convert all of them to an specific format.
certificados$Fecha <- as.Date(certificados$Fecha,format = "%d/%m/%Y")
But im getting NAs due to date format issues.
If you cannot fix this at the source, this code finds both formats:
vec <- c("22/02/2019", "43679", "22/02/2019", "22/01/2019", "28/10/2019", "18/09/2019")
out <- as.Date(vec, format = "%d/%m/%Y")
out
# [1] "2019-02-22" NA "2019-02-22" "2019-01-22" "2019-10-28" "2019-09-18"
isna <- is.na(out)
out[isna] <- as.Date(as.integer(vec[isna]), origin = "1900-01-01")
out
# [1] "2019-02-22" "2019-08-04" "2019-02-22" "2019-01-22" "2019-10-28" "2019-09-18"

How to convert character into Date in R?

I have an excel file where dates are in below format.
01-Jan-2020
03-Jun-2015
I need to convert this in Date. I have tried with many converting techniques.I am getting NA every time.
This should do it:
x <- c("01-Jan-2020", "03-Jun-2015")
as.Date(x, format = "%d-%b-%Y")
#> [1] "2020-01-01" "2015-06-03"
# Or with lubridate
lubridate::dmy(x)
#> [1] "2020-01-01" "2015-06-03"
We can confirm x was converted from character to date with:
y <- list(input = x,
lubridate = lubridate::dmy(x),
base = as.Date(x, format = "%d-%b-%Y"))
str(y)
#> List of 3
#> $ input : chr [1:2] "01-Jan-2020" "03-Jun-2015"
#> $ lubridate: Date[1:2], format: "2020-01-01" "2015-06-03"
#> $ base : Date[1:2], format: "2020-01-01" "2015-06-03"
Download and install "Lubridate" library.
wget https://github.com/tidyverse/lubridate/archive/v1.6.0.tar.gz
sudo R CMD INSTALL v1.6.0.tar.gz
It contains a method called, "parse_date_time2()"
You can parse the date in any format.
Ex.
parse_date_time2("21 Jan 2010", orders = "dmy")
Check for reference.
https://www.displayr.com/r-date-conversion/

i want convert factor to date, the factor is like that :2011-05-05:16:30:04.466

I tried with both the lubricate package and as.Date(), but both show error:
# the factor
> x
[1] '2011-05-05:16:30:04.466 '
873 Levels: '2011-05-05:16:30:04.466 ' ... '2017-08-10:20:05:51.406967'
# try 1
> as.Date(x, format = "%m/%d/%Y")
[1] NA
# try 2
> xx <- mdy(x)
Warning message:
All formats failed to parse. No formats found.
> xx
[1] NA
> xx <- mdy_hms(x)
Warning message:
All formats failed to parse. No formats found.
someone can help me?
To add to the other answer by Jason Clark, there is also as.POSIXct, if you want to keep the times.
getOption("digits.secs")
#NULL
options(digits.secs = 6)
x <- factor('2011-05-05:16:30:04.466')
y <- as.POSIXct(x, format = "%Y-%m-%d:%H:%M:%OS")
y
#[1] "2011-05-05 16:30:04.466 BST"
class(y)
#[1] "POSIXct" "POSIXt"
It looks like your problem might be the format. The default format in as.Date is "%Y-%m-%d" which seems to take care of the example.
> as.Date(as.factor('2011-05-05:16:30:04.466 '), format = "%m/%d/%Y")
[1] NA
> as.Date(as.factor('2011-05-05:16:30:04.466 '))
[1] "2011-05-05"
> as.Date(as.factor('2011-05-05:16:30:04.466 '), format = "%Y-%m-%d")
[1] "2011-05-05"

How to go from yyyy-mm-dd to dd-mm-yyyy?

The follwing code:
date.seq <- as.Date("2007-10-01"):as.Date("2007-10-31")
new.dates <- data.frame(date = as.Date(date.seq, origin = "1970-01-01"))
gives the following output:
> new.dates
date
1 2007-10-01
2 2007-10-02
3 2007-10-03
4 2007-10-04
5 2007-10-05
I would like to have the dates in dd-mm-yyyy format.
I have tried as.Date(new.dates, "%d/%m/%y") without succes.
a) Parse
d <- as.Date( "06.12.2012", "%d.%m.%Y")
b) Format
strftime(d, "%m-%d-%Y")
or
format(d, "%m-%d-%Y")
so Find the below code.
date.seq <- as.Date("2007-10-01"):as.Date("2007-10-31")
new.dates <- data.frame(date = as.Date(date.seq, origin = "1970-01-01"))
new.dates1 <- as.Date( new.dates$date, "%d.%m.%Y")
strftime(new.dates1, "%m-%d-%Y")
Here's another approach. Just for fun:
sub("^(.*)-(.*-)(.*)$", "\\3-\\2\\1", new.dates[[1]])
# [1] "01-10-2007" "02-10-2007" "03-10-2007" "04-10-2007" "05-10-2007"
# [6] "06-10-2007" "07-10-2007" "08-10-2007" "09-10-2007" "10-10-2007"
# [11] "11-10-2007" "12-10-2007" "13-10-2007" "14-10-2007" "15-10-2007"
# [16] "16-10-2007" "17-10-2007" "18-10-2007" "19-10-2007" "20-10-2007"
# [21] "21-10-2007" "22-10-2007" "23-10-2007" "24-10-2007" "25-10-2007"
# [26] "26-10-2007" "27-10-2007" "28-10-2007" "29-10-2007" "30-10-2007"
# [31] "31-10-2007"
This also works:
new.dates <- data.frame(format(as.Date(1:31, origin = "1970-01-01"),"%d/%m/%Y"))
In your original code, as.Date(start):as.Date(end) creates a vector of integers, which you transform back to date using as.Date(...) a second time.

Resources