the string is not in an unambiguous standard format - r

I have data of date and I want to extract the month's name and its year:
>head(merged.tables$Date)
2015-07-31
2013-01-12
2014-01-03
2014-12-03
2013-11-13
2013-10-27
In other word I need to get the result arranged in ascending order like this:
January_2013
October_2013
November_2013
January_2014
December_2014
July_2015
So I tried to use this code to convert first as shown in the code above.
merged.tables$Date <-paste(months(as.Date(merged.tables$Date)),year(as.Date(merged.tables$Date)),sep="_")
But It show me this error:
Error in charToDate(x) :
character string is not in a standard unambiguous format
I tried to adapt this solution character string is not in a standard unambiguous format.
But I can't resolve it!
Thank you for your help

You can use order on the original dates to get the correct order.
First, read in your data example.
Date <- scan(what = character(), text = '
2015-07-31
2013-01-12
2014-01-03
2014-12-03
2013-11-13
2013-10-27')
Date <- as.Date(Date)
Now, reformat and order them.
inx <- order(Date)
newDate <- format(Date, format = "%B_%Y")[inx]
newDate
#[1] "January_2013" "October_2013" "November_2013" "January_2014"
#[5] "December_2014" "July_2015"
Note that this assumes that the dates are of class Date.

Try this (passing your date to character):
merged.tables$Date <-paste(months(as.Date(as.character(merged.tables$Date))),year(as.Date(as.character(merged.tables$Date))),sep="_")
If you build your data.frame like this, you don't have that error:
merged.tables<-data.frame(Date=c("2015-07-31","2013-01-12",
"2014-01-03",
"2014-12-03",
"2013-11-13",
"2013-10-27"))
I suppose that the problem is related to the class of your data.
Ordering:
merged.tables$Date2 <-paste(months(as.Date(as.character(merged.tables$Date))),year(as.Date(as.character(merged.tables$Date))),sep="_")
merged.tables[order(merged.tables$Date),]
Date Date2
2 2013-01-12 gennaio_2013
6 2013-10-27 ottobre_2013
5 2013-11-13 novembre_2013
3 2014-01-03 gennaio_2014
4 2014-12-03 dicembre_2014
1 2015-07-31 luglio_2015

Related

convert orderdate of format m/d/yy to YYYY-MM-DD in R

My orderdate is in factor and i want to convert it into from mm/dd/yy format to YYYY-MM-DD format.
orderdate : Factor w/ 155932 levels "1/1/2017 1:05:00 AM",..: 41 1 1 89 100 102 106 107 119 122 ...
I tried couple of things:
orders2017$newdate <- (factor(orders2017$orderdate))
orders2017$newdate1 <- as.Date(orders2017$newdate,format="%Y-%m-%d")
but nothing is working out and giving me new columns as empty. Any help is appreciated
If you really have values like "1/1/2017 1:05:00 AM" then those aren't dates, they are date times, and as such you have to specify formatting characters for both the date and time parts.
So, first you need to get your date times into a form R understands as such (e.g. POSIXct) by specifying all the parts of the date time:
test <- as.POSIXct("1/1/2017 1:05:00 AM", format = '%m/%d/%Y %I:%M:%S %p')
test
> test
[1] "2017-01-01 01:05:00 CST"
See ?strftime if you are not familiar with all the formatting placeholders used above, and note the conditions for use of %I and %p.
Then you can convert the POSIXct vector into the date format you desire
format(test, format = '%Y-%m-%d')
> format(test, format = '%Y-%m-%d')
[1] "2017-01-01"
A complication for you is that R has converted your character date times into a factor, so you need to convert them back to a character vector before converting to date times. For example (not tested as you didn't supply example data)
orders2017 <- transform(orders2017,
orderdate = as.POSIXct(as.character(orderdate),
format = '%m/%d/%Y %I:%M:%S %p'))
orders2017 <- transform(orders2017,
newdate = format(orderdate, format = '%Y-%m-%d'))
You were really close with as.Date(orders2017$newdate,format="%Y-%m-%d"), you just need to make the format string match your actual format.
Your actual format is mm/dd/YYYY, so use %m/%d/%Y as the format string:
as.Date("1/1/2017 1:05:00 AM", format = "%m/%d/%Y")
# [1] "2017-01-01"
Then the default printing of Date format objects is what you want.
So for your data,
orders2017$newdate1 <- as.Date(orders2017$newdate,format="%Y/%m/%d")
The time part will just be ignored.

How to convert numeric values to time without the date?

I want convert numeric values to time without the date for the data like 1215,1423,1544,1100,0645,1324 in R.
These data has to read like 12:15,14:23,15:44.
I was trying as.POSIXct.
We can use strptime with format
format(strptime(sprintf("%04d", v1), "%H%M"), "%H:%M")
The above output is character class, but if we needed a times class, then we can use times from chron on a "HH:MM:SS" format created with sub or from the above code
library(chron)
times(sub("(.{2})(.{2})","\\1:\\2:", sprintf("%04d00", v1)))
#[1] 12:15:00 14:23:00 15:44:00 11:00:00 06:45:00 13:24:00
Or
times(format(strptime(sprintf("%04d", v1), "%H%M"), "%H:%M:%S"))
data
v1 <- c( 1215,1423,1544,1100,0645,1324)

Split dates separately

I have a date variable
date
15APR16:00:00:04
17APR16:00:06:35
18APR16:00:05:07
18APR16:00:00:56
19APR16:00:08:07
18APR16:00:00:07
22APR16:00:03:07
I want split the variable into two as date and time seperatly.
When I tried
a <- strftime(date, format="%H:%M:%S"), it is showing
Error in as.POSIXlt.default(x, tz = tz) : do not know how to
convert 'x' to class “POSIXlt”
When I tried to see the data type, it shows it as function. How to convert this into date and split into two variables?
The reason you are getting that error is because your date variable doesn't have the right format yet. You should first convert your date variable to a POSIX class with strptime:
dat$date <- strptime(dat$date, format = '%d%b%y:%H:%M:%S')
After that you can use format to extract the time from that variable:
dat$time <- format(dat$date, "%H:%M:%S")
For extracting the date, it is preferrably to use as.Date:
dat$dates <- as.Date(dat$date)
Those steps will give the following result:
> dat
date time dates
1 2016-04-15 00:00:04 00:00:04 2016-04-15
2 2016-04-17 00:06:35 00:06:35 2016-04-17
3 2016-04-18 00:05:07 00:05:07 2016-04-18
4 2016-04-18 00:00:56 00:00:56 2016-04-18
5 2016-04-19 00:08:07 00:08:07 2016-04-19
6 2016-04-18 00:00:07 00:00:07 2016-04-18
7 2016-04-22 00:03:07 00:03:07 2016-04-22
Alternative you could use the lubridate package (as also shown in the other answer):
library(lubridate)
dat$date <- dmy_hms(dat$date)
Used data:
dat <- read.table(text="date
15APR16:00:00:04
17APR16:00:06:35
18APR16:00:05:07
18APR16:00:00:56
19APR16:00:08:07
18APR16:00:00:07
22APR16:00:03:07", header=TRUE, stringsAsFactor=FALSE)
Package lubridate makes converting text to dates easy
library(lubridate)
x <-dmy_hms("15APR16:00:00:04")
format(x, "%H:%M:%S") # extract time
[1] "00:00:04"
format(x, "%d-%m-%Y") # extract date
[1] "15-04-2016"

Format two kinds of factor dates in R

I have two sets of date looking strings; either 31.3.14 or 31/3/14
I would like to format them to 31-3-2014
Now I know how to format each of them to desired format, but I don't know how to distinguish them and apply the approach bellow.
For this format 31.3.14 :
format(as.Date(as.character("31.3.14"), "%d.%m.%y"), "%d-%m-%Y")
For this format 31/3/14 :
format(as.Date(as.character("31/3/14"), "%d/%m/%Y"), "%d-%m-%Y"))
I have this sorts of dates in a dataframe column randomly so I would need to apply given method for the right set of format.
EDIT: sorry I have also different kinds of dates, also: "2013-04-01" here the solution provided with dmy function fails.
Could also do it with base R by removing punctuations first
Dates <- c("31.3.14", "31/3/14")
format(as.Date(gsub("[[:punct:]]", "-", Dates), format = "%d-%m-%y"), "%d-%m-%Y")
## [1] "31-03-2014" "31-03-2014"
Hadley Wickham's Lubridate package makes this easy.
> require(lubridate)
> test <- data.frame(raw = c("31.3.14", "31/3/14"))
> test$formatted <- dmy(test$raw)
> test
raw formatted
1 31.3.14 2014-03-31
2 31/3/14 2014-03-31
EDIT:
Based on the edit to the question, one can use ifelse() within a function to detect a four-digit sequence at the start of the date string.
require(stringr)
myDateFun <- function(x){
z <- ifelse(str_detect(x, "^\\d{4}") == TRUE,
ymd(x), dmy(x) )
z <- as.POSIXlt(z, origin = "1970-01-01")
z <- format(z, "%Y-%m-%d")
return(z)
}
test <- data.frame(raw = c("31.3.14", "31/3/14", "2014-3-31"))
test$formatted.2 <- myDateFun(test$raw)
test
raw formatted formatted.2
1 31.3.14 2014-03-31 2014-03-31
2 31/3/14 2014-03-31 2014-03-31
3 2014-3-31 <NA> 2014-03-31

Transform variable into a %H:%M time format in R

I have this vector representing time recorded as hours (0 to 24) and minute (0 to 59). I would like to transform it into a %H:%M time format in R such that I can use function like difftime.
str(SF5$ES_TIME)
int [1:11452] 1940 600 5 1455 1443 2248 1115 900 200 420 ...
This is what I've tried, but in both cases, I got an error:
>SF5$time1<-as.POSIXct(SF5$ES_TIME, format = "%H:%M",tz="EST")
Error in as.POSIXct.numeric(SF5$ES_TIME, format = "%H:%M", tz = "EST") :
'origin' must be supplied
SF5$time1<-as.POSIXct(as.character(SF5$ES_TIME), format="%H:%M",tz="")
> str(SF5$time1)
POSIXct[1:11452], format: NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA ...
Any help or reading suggestions would be much appreciated!
Thank you,
Aurelie
Well, the error message tells you to provide origin and a minute is 60 seconds, so:
SF5 <- list(ES_TIME=as.integer(c(1940,600,5,1455,1443,2248,1115,900,200,420)))
x <- as.POSIXct(SF5$ES_TIME*60, origin="1970-01-01")
format(x, format="%H:%M")
#[1] "08:20" "10:00" "00:05" "00:15" "00:03" "13:28" "18:35" "15:00" "03:20" "07:00"
Note that the POSIXct date is just a number (with a class), so you need the format call to print it as you want - the default printing of x would print the full date info (year/month/day etc).
...any origin date would do since you don't care about it, but 1970-01-01 is the usual origin...
I was able to crack down the code! Thank you all for your tip!
#1) as suggested by Justin : put all numbers into four digits with zero padding
SF5$ES_TIME2<-sprintf("%04d",SF5$ES_TIME)
#2) Matched these %H%M with their corresponding date %y-%m-%d
SF5$ES.datetime <- paste(SF5$ES_TIME2,SF5$ES_DATE,sep=" ")
#3) Transform into Date-Time format
SF5$ES.datetime2 <- as.POSIXct(SF5$ES.datetime,format="%H%M %y-%m-%d", tz="")
# Did the same for my other time-date of interest
SF5$SH_TIME2<-sprintf("%04d",SF5$SH_TIME)
SF5$SH.datetime <- paste(SF5$SH_TIME2,SF5$SH_DATE,sep=" ")
SF5$SH.datetime2 <- as.POSIXct(SF5$SH.datetime,format="%H%M %y-%m-%d", tz="")
# Calculate the time difference between the 2 date-time in hours
SF5$duration<-difftime(SF5$SH.datetime2,SF5$ES.datetime2,units="hours",tz="")

Resources