This is probably asked many times but I couldn't find related resource and just can't get it right. I have a data frame with an HourStamp column in yyyymmddHH format and I need to extract the HH from it. How can I do it?
As an example:
HourStamp Hour
2013050100 00
2013050101 01
2013050102 02
...
I need that Hour column added. Thanks!
Like #Klaus already commented, in this case a simple substr would to the trick, i.e. substr('2013050100', 9, 10). Remember that substr is vectorized so you can simply do:
df$Hour = substr(df$HourStamp, 9, 10)
A more flexible and powerful way of dealing with dates/times is to simply convert HourStamp into a real R date object:
d = strptime('2013050100', format = '%Y%m%d%H')
strftime(d, '%H')
[1] "00"
In this case the strptime solution is a bit cumbersome, but it allows for stuff like:
> strftime(d, '%A %d of %B in the year %Y')
[1] "Wednesday 01 of May in the year 2013"
or:
strftime(d, 'file%Y%d.csv')
[1] "file201301.csv"
or in vectorized form for your example:
df$time = strptime(df$HourStamp, format = '%Y%m%d%H')
df$Hour = strftime(df$time, '%H')
Related
I have a column of dates written as monthyear in the format:
11960 - this would be Jan 1960
121960 - this would be Dec 1960
I would like to convert this column into a day-month-year format assuming the first of the month as each date.
I have tried (using one number as an example as opposed to dt$dob)
x <- sprintf("%08d%", 11960)
and then x <- as.date(x, format = "%d%m%Y)
but this gives me NAs as I assume it doesn't like the 00 at the start
So I tried pasting 01 to each value but this pastes it to the end (R noob here). I was thinking maybe posting 01 to the start and then using the sprintf function may work still:
paste 01 to start of 11960 = 011960
sprintf("%08d%", 011960) to maybe give 0101960?
Then use as.Date to convert?
Many thanks for your help
i used paste0() instead of sprintf, but it seems it works.
> x<-paste0("010",11960)
> x
[1] "01011960"
> as.Date(x , format = "%d%m%Y" )
[1] "1960-01-01"
EDIT for 2 digit months i use ifelse() and nchar()
y<-c(11960,11970,11980, 111960,111970,111980)
x<-ifelse(nchar(y) == 5,paste0("010",y),paste0("01",y))
> x
[1] "01011960" "01011970" "01011980" "01111960" "01111970" "01111980"
as.Date(x , format = "%d%m%Y" )
[1] "1960-01-01" "1970-01-01" "1980-01-01" "1960-11-01" "1970-11-01" "1980-11-01"
I am trying to get Date column from an excel data. The format of date in excel is like Wednesday-September 7-2011.
How do I handle dates in such format? I've read the documentation on Date and cannot find any method.
as.Date("Wednesday-September 7-2011", "%A-%B %d-%Y")
# [1] "2011-09-07"
https://www.stat.berkeley.edu/~s133/dates.html
If all your dates follow the same format, then I 'd suggest to remove the day and parse the rest, i.e.
x <- 'Wednesday - September 7 - 2011'
y <- paste(strsplit(x, ' - ')[[1]][-1], collapse = ' ')
#which gives [1] "September 7 2011"
as.POSIXct(y, format = '%B %d %Y')
#[1] "2011-09-07 EEST"
I'd probably strip out the weekday name and then parse the rest of the date. For example:
x <- "Wednesday-September 7-2011"
pos <- regexpr("-", x)
y<- (substr(x,pos+1,nchar(x)))
z<- parse_date(y, format = "%B %d-%Y")
Hey awesome community,
so I got this pretty big dataset and unfortunately the date columns is in the following format:
20112016
28112016
2122016
6122016
11122016
Its a simple numeric format. How can i transfer it to standard dates format like 02-12-2016.
betterDates <-as.Date(as.character(betterDates), "%e%m%Y")
The format of days/months need to be the same with 2 digits, giving a total of 8 digits for each date. In case where day is 1 or 2 or... or 9, we can use sprintf to make them 01, 02, ..., 09, i.e.
x <-c(20112016, 28112016, 2122016, 6122016, 11122016)
as.Date(sprintf('%08d', x), '%d%m%Y')
#[1] "2016-11-20" "2016-11-28" "2016-12-02" "2016-12-06" "2016-12-11"
The lubridate package is pretty handy in these situations:
x <-c(20112016, 28112016, 2122016, 6122016, 11122016)
lubridate::dmy(x)
[1] "2016-11-20" "2016-11-28" "2016-12-02" "2016-12-06" "2016-12-11"
Currently my dataframe has dates displayed in the 'Date' column as 01/01/2007 etc I would like to convert these into a week/year value i.e. 01/2007. Any ideas?
I have been trying things like this and getting no where...
enviro$Week <- strptime(enviro$Date, format= "%W/%Y")
You have to first convert to date, then you can convert back to the week of the year using format, for example:
### Converts character to date
test.date <- as.Date("10/10/2014", format="%m/%d/%Y")
### Extracts only Week of the year and year
format(test.date, format="Week number %W of %Y")
[1] "Week number 40 of 2014"
### Or if you prefer
format(date, format="%W/%Y")
[1] "40/2014"
So, in your case, you would do something like this:
enviro$Week <- format(as.Date(enviro$Date, format="%m/%d/%Y"), format= "%W/%Y")
But remember that the part as.Date(enviro$Date, format="%m/%d/%Y") is only necessary if your data is not in Date format, and you also should put the right format parameter to convert your character to Date, if that is the case.
What is the class of enviro$Date? If it is of class Date there is probably a better way of doing this, otherwise you can try
v <- strsplit(as.character(enviro$Date), split = "/")
weeks <- sapply(v, "[", 2)
years <- sapply(v, "[", 3)
enviro$Week <- paste(weeks, years, sep = "/")
I have an file with birthdays in %d%b%y format. Some eg.
# "01DEC71" "01AUG54" "01APR81" "01MAY81" "01SEP83" "01FEB59"
I tried to reformat the date as
o108$fmtbirth <- format(as.Date(o108$birth, "%d%b%y"), "%Y/%m/%d")
and this is the result
# "1971/12/01" "2054/08/01" "1981/04/01" "1981/05/01" "1983/09/01" "2059/02/01"
These are birthdays and I see 2054. From this page I see that year values between 00 and 68 are coded as 20 for century. Is there a way to toggle this, in my case I want only 00 to 12 to be coded as 20.
1) chron. chron uses 30 by default so this will convert them converting first to Date (since chron can't read those sorts of dates) reformatting to character with two digit years into a format that chron can understand and finally back to Date.
library(chron)
xx <- c("01AUG11", "01AUG12", "01AUG13") # sample data
as.Date(chron(format(as.Date(xx, "%d%b%y"), "%m/%d/%y")))
That gives a cutoff of 30 but we can get a cutoff of 13 using chron's chron.year.expand option:
library(chron)
options(chron.year.expand =
function (y, cut.off = 12, century = c(1900, 2000), ...) {
chron:::year.expand(y, cut.off = cut.off, century = century, ...)
}
)
and then repeating the original conversion. For example assuming we had run this options statement already we would get the following with our xx :
> as.Date(chron(format(as.Date(xx, "%d%b%y"), "%m/%d/%y")))
[1] "2011-08-01" "2012-08-01" "1913-08-01"
2) Date only. Here is an alternative that does not use chron. You might want to replace "2012-12-31" with Sys.Date() if the idea is that otherwise future dates are really to be set 100 years back:
d <- as.Date(xx, "%d%b%y")
as.Date(ifelse(d > "2012-12-31", format(d, "19%y-%m-%d"), format(d)))
EDIT: added Date only solution.
See response from related thread:
format(as.Date("65-05-14", "%y-%m-%d"), "19%y-%m-%d")
o108$fmtbirth <- format(as.Date(o108$birth, "%d%b%y"), "%Y/%m/%d")
o108$fmtbirth <- as.Date(ifelse(o108$fmtbirth > Sys.Date(),
format(o108$fmtbirth, "19%y-%m-%d"),
format(o108$fmtbirth)))