I am trying to split this dataframe by the date and ID:
Id Date Returns
1 039229109 1996-12-31 0.4739285
2 039229109 1997-01-02 -1.8867910
3 039229109 1997-01-03 0.4807711
4 056180102 1996-12-31 -4.9504940
5 056180102 1997-01-02 2.6041627
6 056180102 1997-01-03 0.0000000
7 096650106 1996-12-31 -2.0872890
8 096650106 1997-01-02 -1.8410861
9 096650106 1997-01-03 1.4807463
So that it will look like this:
Date 039229109 056180102 096650106
1 1996-12-31 0.4739285 -4.950494 -2.087289
2 1997-01-02 -1.8867910 2.604163 -1.841086
3 1997-01-03 0.4807711 0.000000 1.480746
I have tried using:
> aggregate(data,by = list(data$Date),identity)
But that returns this:
Group.1 Id.1 Id.2 Id.3 Date.1 Date.2 Date.3 Returns.1 Returns.2 Returns.3
1 1996-12-31 039229109 056180102 096650106 9861 9861 9861 0.4739285 -4.9504940 -2.0872890
2 1997-01-02 039229109 056180102 096650106 9863 9863 9863 -1.8867910 2.6041627 -1.8410861
3 1997-01-03 039229109 056180102 096650106 9864 9864 9864 0.4807711 0.0000000 1.4807463
I am very unfamiliar with aggregate, and feel like this should be simple, but I cannot figure out a way to do this. (I tried using reshape, but do not understand it, and could not get meaningful results.)
Thanks for your help!
EDIT: Changed and formatted the data.
This is really more of a re-shaping problem than an aggregating problem. That's probably why you are having a difficult time using aggregate
. So if this is your sample data
data<-structure(list(Id = c("039229109", "039229109", "039229109",
"056180102", "056180102", "056180102", "096650106", "096650106",
"096650106", "172736100", "172736100", "172736100", "208368100",
"208368100", "208368100"), Date = structure(c(9861, 9863, 9864,
9861, 9863, 9864, 9861, 9863, 9864, 9861, 9863, 9864, 9861, 9863,
9864), class = "Date"), fg.total.returnc = c(0.4739285, -1.886791,
0.4807711, -4.950494, 2.6041627, 0, -2.087289, -1.8410861, 1.4807463,
-0.8130074, 0.8196712, 0.8130074, -0.1253128, -0.6273508, 0.1262665
)), .Names = c("Id", "Date", "fg.total.returnc"), row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15"), class = "data.frame")
then you can use the base function reshape()
. For example
ww <- reshape(data, timevar="Id", idvar="Date", direction="wide")
names(ww) <- gsub("fg.total.returnc.","", names(ww), fixed=T)
ww
# Date 039229109 056180102 096650106 172736100 208368100
# 1 1996-12-31 0.4739285 -4.950494 -2.087289 -0.8130074 -0.1253128
# 2 1997-01-02 -1.8867910 2.604163 -1.841086 0.8196712 -0.6273508
# 3 1997-01-03 0.4807711 0.000000 1.480746 0.8130074 0.1262665
This is somewhat awkward because the roles of the IDs and Dates are switched in your example. I think the nicer approach is to use the reshape2
library.
library(reshape2)
dcast(data, Date~Id)
# Date 039229109 056180102 096650106 172736100 208368100
# 1 1996-12-31 0.4739285 -4.950494 -2.087289 -0.8130074 -0.1253128
# 2 1997-01-02 -1.8867910 2.604163 -1.841086 0.8196712 -0.6273508
# 3 1997-01-03 0.4807711 0.000000 1.480746 0.8130074 0.1262665
A nice alternative in base R is to use xtabs
:
> xtabs(fg.total.returnc ~ Date + Id, data)
Id
Date 039229109 056180102 096650106 172736100 208368100
1996-12-31 0.4739285 -4.9504940 -2.0872890 -0.8130074 -0.1253128
1997-01-02 -1.8867910 2.6041627 -1.8410861 0.8196712 -0.6273508
1997-01-03 0.4807711 0.0000000 1.4807463 0.8130074 0.1262665
The result is a matrix
with class
es of xtabs
and table
, so if you want a data.frame
, be sure to wrap the above with as.data.frame.matrix
and not just as.data.frame
(since the latter would just put you right back where you started).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.