Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In R how can I split a dataframe by date

I have a dataframe where one column is a date time (chron). I would like to split this dataframe into a list of dataframes split by the date part only. So each dataframe will have all the data for that day. I looked at split function but not sure how to use part of a column value?

like image 933
Mark Avatar asked Dec 27 '22 03:12

Mark


1 Answers

say you have this data.frame :

    df <- data.frame(date=rep(seq.POSIXt(as.POSIXct("2010-01-01 15:26"), by="day", length.out=3), each=3), var=rnorm(9))
> df
                 date         var
1 2010-01-01 15:26:00 -0.02814237
2 2010-01-01 15:26:00 -0.26924825
3 2010-01-01 15:26:00 -0.57968310
4 2010-01-02 15:26:00  0.88089757
5 2010-01-02 15:26:00 -0.79954092
6 2010-01-02 15:26:00  1.87145778
7 2010-01-03 15:26:00  0.93234835
8 2010-01-03 15:26:00  1.29130038
9 2010-01-03 15:26:00 -1.09841234

to split by day you just need:

 > split(df, as.Date(df$date))
$`2010-01-01`
                 date         var
1 2010-01-01 15:26:00 -0.02814237
2 2010-01-01 15:26:00 -0.26924825
3 2010-01-01 15:26:00 -0.57968310

$`2010-01-02`
                 date        var
4 2010-01-02 15:26:00  0.8808976
5 2010-01-02 15:26:00 -0.7995409
6 2010-01-02 15:26:00  1.8714578

$`2010-01-03`
                 date        var
7 2010-01-03 15:26:00  0.9323484
8 2010-01-03 15:26:00  1.2913004
9 2010-01-03 15:26:00 -1.0984123

EDIT:

the above method is consistent with chron datetime object too:

x <- chron(dates = "02/27/92", times = "22:29:56")
> x
[1] (02/27/92 22:29:56)
> as.Date(x)
[1] "1992-02-27"

EDIT 2

making sure that as.Date doesn't change your data is crucial, see here:

# I'm using "DSTday" to make a sequece of one entire _apparent_ day
x <- rep(seq.POSIXt(as.POSIXct("2010-03-27 00:31"), by="DSTday", length.out=3))
> x
[1] "2010-03-27 00:31:00 GMT" "2010-03-28 00:31:00 GMT" "2010-03-29 00:31:00 BST"
> as.Date(x)
[1] "2010-03-27" "2010-03-28" "2010-03-28"

the third item is in the summer time and as.Date retrieve the actual day, i.e. minus one hour. To avoid this:

> as.Date(cut(x, "DSTday"))
[1] "2010-03-27" "2010-03-28" "2010-03-29"
like image 131
Michele Avatar answered Jan 05 '23 20:01

Michele