How keep only date variable without time-field string [duplicate] - r

This question already has answers here:
Date conversion from POSIXct to Date in R
(3 answers)
Closed 5 years ago.
My question takes a general aspect comparing to which was proposed here How to remove time-field string from a date-as-character variable?.
In fact, suppose I have this date type variable:
> head(DataDia$Date)
[1] "2016-09-13 15:56:30.827" "2016-12-12 13:39:17.537" "2016-09-16 21:57:24.977" "2016-09-23 11:19:22.010"
[5] "2017-01-11 20:06:58.490" "2016-10-21 23:40:43.927"
How do I delete all time-field strings and just keep the date format. SO that I get this:
> head(DataDia$Date)
[1] "2016-09-13" "2016-12-12" "2016-09-16" "2016-09-23"
[5] "2017-01-11" "2016-10-21"
Note please that I am working on a data table. So I need a way using data.table
operations.

Just use as.Date(DataDia$Date).

You Can use:
as.POSIXct(Df$Date,format='%Y-%m-%d',tz= "UTC")

Combining as.Date and as.character
x = c("2016-09-13 15:56:30.827", "2016-12-12 13:39:17.537", "2016-09-16 21:57:24.977", "2016-09-23 11:19:22.010",
"2017-01-11 20:06:58.490", "2016-10-21 23:40:43.927")
y = as.character(as.Date(x, format = "%Y-%m-%d"))
y
[1] "2016-09-13" "2016-12-12" "2016-09-16" "2016-09-23" "2017-01-11" "2016-10-21"

Related

How to make never ending quarters in r studio [duplicate]

I want to generate a sequence of dates with one quarter interval, with a starting date and ending date. I have below code :
> seq(as.Date('1980-12-31'), as.Date('1985-06-30'), by = 'quarter')
[1] "1980-12-31" "1981-03-31" "1981-07-01" "1981-10-01" "1981-12-31"
[6] "1982-03-31" "1982-07-01" "1982-10-01" "1982-12-31" "1983-03-31"
[11] "1983-07-01" "1983-10-01" "1983-12-31" "1984-03-31" "1984-07-01"
[16] "1984-10-01" "1984-12-31" "1985-03-31"
As you can see, this is not generating right sequence, as I dont understand how the date "1981-07-01" is coming here, I would expect "1981-06-30".
Is there any way to generate such sequence correctly with quarter interval?
Thanks for your time.
The from and to dates in the question are both end-of-quarter dates so we assume that that is the general case you are interested in.
1) Create a sequence of yearqtr objects yq and then convert them to Date class. frac=1 tells it s to use the end of the month. Alternately just use yq since that directly models years with quarters.
library(zoo)
from <- as.Date('1980-12-31')
to <- as.Date('1985-06-30')
yq <- seq(as.yearqtr(from), as.yearqtr(to), by = 1/4)
as.Date(yq, frac = 1)
giving;
[1] "1980-12-31" "1981-03-31" "1981-06-30" "1981-09-30" "1981-12-31"
[6] "1982-03-31" "1982-06-30" "1982-09-30" "1982-12-31" "1983-03-31"
[11] "1983-06-30" "1983-09-30" "1983-12-31" "1984-03-31" "1984-06-30"
[16] "1984-09-30" "1984-12-31" "1985-03-31" "1985-06-30"
2) or without any packages add 1 to from and to so that they are at the beginning of the next month, create the sequence (it has no trouble with first of month sequences) and then subtract 1 from the generated sequence giving the same result as above.
seq(from + 1, to + 1, by = "quarter") - 1
Using the clock package and R >= 4.1:
library(clock)
seq(year_quarter_day(1980, 4), year_quarter_day(1985, 2), by = 1) |>
set_day("last") |>
as_date()
# [1] "1980-12-31" "1981-03-31" "1981-06-30" "1981-09-30" "1981-12-31" "1982-03-31" "1982-06-30" "1982-09-30" "1982-12-31"
# [10] "1983-03-31" "1983-06-30" "1983-09-30" "1983-12-31" "1984-03-31" "1984-06-30" "1984-09-30" "1984-12-31" "1985-03-31"
# [19] "1985-06-30"
Note that this includes the final quarter. I don't know if that was your intent.
Different definition of "quarter". A quarter might well be (although it is not in R) 365/4 days. Look at output of :
as.Date('1980-12-31')+(365/4)*(0:12)
#[1] "1980-12-31" "1981-04-01" "1981-07-01" "1981-09-30" "1981-12-31" "1982-04-01" "1982-07-01" "1982-09-30"
#[9] "1982-12-31" "1983-04-01" "1983-07-01" "1983-09-30" "1983-12-31"
In order to avoid the days of the month from surprising you, you need to use a starting day of the month between 1 and 28, at least in non-leap years.
seq(as.Date('1981-01-01'), as.Date('1985-06-30'), by = 'quarter')
[1] "1981-01-01" "1981-04-01" "1981-07-01" "1981-10-01" "1982-01-01" "1982-04-01" "1982-07-01" "1982-10-01"
[9] "1983-01-01" "1983-04-01" "1983-07-01" "1983-10-01" "1984-01-01" "1984-04-01" "1984-07-01" "1984-10-01"
[17] "1985-01-01" "1985-04-01"

Creating Vectors sequence in R [duplicate]

This question already has answers here:
Alternate, interweave or interlace two vectors
(2 answers)
Closed 1 year ago.
I want to write a R program that creates the vector 0.1^3, 0.2^1, 0.1^6, 0.2^4, ..., 0.1^36, 0.2^34.
v=c(seq(3,36,3))
w=c(seq(1,34,3))
x=c(0.1^v)
y=c(0.2^w)
z=c(x,y)
Please help.
rbind to a matrix and convert to vector again:
c(rbind(x, y))
Or more directly:
rep(c(0.1, 0.2), 12)^c(rbind(seq(3,36,3), seq(1,34,3)))
You can use matrix to create the desired vector.
c(matrix(z, 2, byrow=TRUE))
# [1] 1.000000e-03 2.000000e-01 1.000000e-06 1.600000e-03 1.000000e-09
# [6] 1.280000e-05 1.000000e-12 1.024000e-07 1.000000e-15 8.192000e-10
#[11] 1.000000e-18 6.553600e-12 1.000000e-21 5.242880e-14 1.000000e-24
#[16] 4.194304e-16 1.000000e-27 3.355443e-18 1.000000e-30 2.684355e-20
#[21] 1.000000e-33 2.147484e-22 1.000000e-36 1.717987e-24

Concatenating two vectors in R [duplicate]

This question already has answers here:
How to concatenate factors, without them being converted to integer level?
(9 answers)
Closed 5 years ago.
I want to concatenate two vectors one after the other in R. I have written the following code to do it:
> a = head(tracks_listened_train)
> b = head(tracks_listened_test)
> a
[1] cc1a46ee0446538ecf6b65db01c30cd8 19acf9a5cbed34743ce0ee42ef3cae3e
[3] 9e7fdbf2045c9f814f6c0bed5da9bed7 3441b1031267fbb6009221bf47f9c5e8
[5] 206c8b79bd02beeea200879afc414879 1a7a95e3845a6815060628e847d14362
18585 Levels: 0001a423baf29add84af6ec58aeb5b90 ...
> b
[1] 7251a7694b79aa9a39f9a1a5f5c8a253 2f362377ef0e7bca112233fdda22a79c
[3] c1196625b1b733b62c43935334e1d190 58e41e462af4185b08231a41453c3faf
[5] 1cc2517fa9c037e02a14ce0950a28f67
10186 Levels: 0001a423baf29add84af6ec58aeb5b90 ...
> res = c(a,b)
> res
[1] 14898 1898 11556 3859 2408 1950 4473 1865 7674 3488 1130
However, I get the unexpected result of the resultant vector. What could the problem be?
We need to convert the factor class to character class
c(as.character(a), as.character(b))
The reason we get numbers instead of the character is based on the storage mode of factor i.e. an integer. So when we do the concatenation, it coerces to the integer mode

R: generate dataframe of Friday dates for the year [duplicate]

This question already has answers here:
Get Dates of a Certain Weekday from a Year in R
(3 answers)
Closed 9 years ago.
I would like to generate a dataframe that contains all the Friday dates for the whole year.
Is there a simple way to do this?
eg for December 2013: (6/12/13,13/12/13,20/12/13,27/12/13)
Thank you for your help.
I'm sure there is a simpler way, but you could brute force it easy enough:
dates <- seq.Date(as.Date("2013-01-01"),as.Date("2013-12-31"),by="1 day")
dates[weekdays(dates)=="Friday"]
dates[format(dates,"%w")==5]
Building on #Frank's good work, you can find all of any specific weekday between two dates like so:
pick.wkday <- function(selday,start,end) {
fwd.7 <- start + 0:6
first.day <- fwd.7[as.numeric(format(fwd.7,"%w"))==selday]
seq.Date(first.day,end,by="week")
}
start and end need to be Date objects, and selday is the day of the week you want (0-6 representing Sunday-Saturday).
i.e. - for the current query:
pick.wkday(5,as.Date("2013-01-01"),as.Date("2013-12-31"))
Here is a way.
d <- as.Date(1:365, origin = "2013-1-1")
d[strftime(d,"%A") == "Friday"]
Alternately, this would be a more efficient approach for generating the data for an arbitrary number of Fridays:
wk1 <- as.Date(seq(1:7), origin = "2013-1-1") # choose start date & make 7 consecutive days
wk1[weekdays(wk1) == "Friday"] # find Friday in the sequence of 7 days
seq.Date(wk1[weekdays(wk1) == "Friday"], length.out=50, by=7) # use it to generate fridays
by=7 says go to the next Friday.
length.out controls the number of Fridays to generate. One could also use to to control how many Fridays are generated (e.g. use to=as.Date("2013-12-31") instead of length.out).
Takes a year as input and returns only the fridays...
getFridays <- function(year) {
dates <- seq(as.Date(paste0(year,"-01-01")),as.Date(paste0(year,"-12-31")), by = "day")
dates[weekdays(dates) == "Friday"]
}
Example:
> getFridays(2000)
[1] "2000-01-07" "2000-01-14" "2000-01-21" "2000-01-28" "2000-02-04" "2000-02-11" "2000-02-18" "2000-02-25" "2000-03-03" "2000-03-10" "2000-03-17" "2000-03-24" "2000-03-31"
[14] "2000-04-07" "2000-04-14" "2000-04-21" "2000-04-28" "2000-05-05" "2000-05-12" "2000-05-19" "2000-05-26" "2000-06-02" "2000-06-09" "2000-06-16" "2000-06-23" "2000-06-30"
[27] "2000-07-07" "2000-07-14" "2000-07-21" "2000-07-28" "2000-08-04" "2000-08-11" "2000-08-18" "2000-08-25" "2000-09-01" "2000-09-08" "2000-09-15" "2000-09-22" "2000-09-29"
[40] "2000-10-06" "2000-10-13" "2000-10-20" "2000-10-27" "2000-11-03" "2000-11-10" "2000-11-17" "2000-11-24" "2000-12-01" "2000-12-08" "2000-12-15" "2000-12-22" "2000-12-29"
There are probably more elegant ways to do this, but here's one way to generate a vector of Fridays, given any year.
year = 2007
st <- as.POSIXlt(paste0(year, "/1/01"))
en <- as.Date(paste0(year, "/12/31"))
#get to the next Friday
skip_ahead <- 5 - st$wday
if(st$wday == 6) skip_ahead <- 6 #for Saturdays, skip 6 days ahead.
first.friday <- as.Date(st) + skip_ahead
dates <- seq(first.friday, to=en, by ="7 days")
dates
#[1] "2007-01-05" "2007-01-12" "2007-01-19" "2007-01-26"
# [5] "2007-02-02" "2007-02-09" "2007-02-16" "2007-02-23"
# [9] "2007-03-02" "2007-03-09" "2007-03-16" "2007-03-23"
I think this would be the most efficient way and would also returns all the Friday in the whole of 2013.
FirstWeek <- seq(as.Date("2013/1/1"), as.Date("2013/1/7"), "days")
seq(
FirstWeek[weekdays(FirstWeek) == "Friday"],
as.Date("2013/12/31"),
by = "week"
)

How do I change the index in a csv file to a proper time format?

I have a CSV file of 1000 daily prices
They are of this format:
1 1.6
2 2.5
3 0.2
4 ..
5 ..
6
7 ..
.
.
1700 1.3
The index is from 1:1700
But I need to specify a begin date and end date this way:
Start period is lets say, 25th january 2009
and the last 1700th value corresponds to 14th may 2013
So far Ive gotten this close to this problem:
> dseries <- ts(dseries[,1], start = ??time??, freq = 30)
How do I go about this? thanks
UPDATE:
managed to create a seperate object with dates as suggested in the answers and plotted it, but the y axis is weird, as shown in the screenshot
Something like this?
as.Date("25-01-2009",format="%d-%m-%Y") + (seq(1:1700)-1)
A better way, thanks to #AnandaMahto:
seq(as.Date("2009-01-25"), by="1 day", length.out=1700)
Plotting:
df <- data.frame(
myDate=seq(as.Date("2009-01-25"), by="1 day", length.out=1700),
myPrice=runif(1700)
)
plot(df)
R stores Date-classed objects as the integer offset from "1970-01-01" but the as.Date.numeric function needs an offset ('origin') which can be any staring date:
rDate <- as.Date.numeric(dseries[,1], origin="2009-01-24")
Testing:
> rDate <- as.Date.numeric(1:10, origin="2009-01-24")
> rDate
[1] "2009-01-25" "2009-01-26" "2009-01-27" "2009-01-28" "2009-01-29"
[6] "2009-01-30" "2009-01-31" "2009-02-01" "2009-02-02" "2009-02-03"
You didn't need to add the extension .numeric since R would automticallly seek out that function if you used the generic stem, as.Date, with an integer argument. I just put it in because as.Date.numeric has different arguments than as.Date.character.

Resources