showkey
showkey

Reputation: 358

why all date strings are changed into numbers?

start=as.Date("2013-09-02")
x[1:140]<-start
for(i in 2:140){
  x[i]<-x[i-1]+1 }

what i get is something as such:

[1] "2013-09-02" "2013-09-03" "2013-09-04" "2013-09-05" "2013-09-06"    

when i run :

y<-matrix(x,nrow=20,byrow=TRUE) 
> y

   [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]
 [1,] 15950 15951 15952 15953 15954 15955 15956   

all the string are changed into numbers,why?how can i not to change them in y?

Upvotes: 3

Views: 772

Answers (2)

mrip
mrip

Reputation: 15163

The problem is R doesn't allow matrices to be populated with dates. Both "matrix" and "Date" are classes. The underlying representation of a Date object in R is just an integer. So when you create your matrix y, it takes the underlying data from x (which is an array of integers), adds a dimension attribute, and makes the class "matrix".

There's not any clean way around this problem. There are a few hacks you can use, though. For example, you could explicitly force y to be of class "Date" as well as "matrix" with class(y)<-c("matrix","Date"). y would still print out as just a vector of dates, but you would be able to manipulate it using matrix cordinates:

> class(y)<-c("matrix","Date")
> head(y)
 [1] "2013-09-02" "2013-09-09" "2013-09-16" "2013-09-23" "2013-09-30"
 [6] "2013-10-07" "2013-09-03" "2013-09-10" "2013-09-17" "2013-09-24"
[11] "2013-10-01" "2013-10-08" "2013-09-04" "2013-09-11" "2013-09-18"
[16] "2013-09-25" "2013-10-02" "2013-10-09" "2013-09-05" "2013-09-12"
[21] "2013-09-19" "2013-09-26" "2013-10-03" "2013-10-10" "2013-09-06"
[26] "2013-09-13" "2013-09-20" "2013-09-27" "2013-10-04" "2013-10-11"
[31] "2013-09-07" "2013-09-14" "2013-09-21" "2013-09-28" "2013-10-05"
[36] "2013-10-12" "2013-09-08" "2013-09-15" "2013-09-22" "2013-09-29"
[41] "2013-10-06" "2013-10-13"
> y[1,]
[1] "2013-09-02" "2013-09-03" "2013-09-04" "2013-09-05" "2013-09-06"
[6] "2013-09-07" "2013-09-08"
> y[1,]<-y[1,]+1
> y[1,]
[1] "2013-09-03" "2013-09-04" "2013-09-05" "2013-09-06" "2013-09-07"
[6] "2013-09-08" "2013-09-09"

You could also use a data frame instead of a matrix:

> y<-data.frame(y)
> y<-data.frame(lapply(y,function(x) {class(x)<-"Date";x}))
> head(y)
          X1         X2         X3         X4         X5         X6         X7
1 2013-09-02 2013-09-03 2013-09-04 2013-09-05 2013-09-06 2013-09-07 2013-09-08
2 2013-09-09 2013-09-10 2013-09-11 2013-09-12 2013-09-13 2013-09-14 2013-09-15
3 2013-09-16 2013-09-17 2013-09-18 2013-09-19 2013-09-20 2013-09-21 2013-09-22
4 2013-09-23 2013-09-24 2013-09-25 2013-09-26 2013-09-27 2013-09-28 2013-09-29
5 2013-09-30 2013-10-01 2013-10-02 2013-10-03 2013-10-04 2013-10-05 2013-10-06
6 2013-10-07 2013-10-08 2013-10-09 2013-10-10 2013-10-11 2013-10-12 2013-10-13

A third possiblity is to keep the elements in y in character format, and then convert them to dates using as.Date when you need them:

> y<-matrix(as.character(x),nrow=20,byrow=T)
> head(y)
     [,1]         [,2]         [,3]         [,4]         [,5]        
[1,] "2013-09-02" "2013-09-03" "2013-09-04" "2013-09-05" "2013-09-06"
[2,] "2013-09-09" "2013-09-10" "2013-09-11" "2013-09-12" "2013-09-13"
[3,] "2013-09-16" "2013-09-17" "2013-09-18" "2013-09-19" "2013-09-20"
[4,] "2013-09-23" "2013-09-24" "2013-09-25" "2013-09-26" "2013-09-27"
[5,] "2013-09-30" "2013-10-01" "2013-10-02" "2013-10-03" "2013-10-04"
[6,] "2013-10-07" "2013-10-08" "2013-10-09" "2013-10-10" "2013-10-11"
     [,6]         [,7]        
[1,] "2013-09-07" "2013-09-08"
[2,] "2013-09-14" "2013-09-15"
[3,] "2013-09-21" "2013-09-22"
[4,] "2013-09-28" "2013-09-29"
[5,] "2013-10-05" "2013-10-06"
[6,] "2013-10-12" "2013-10-13"
> as.Date(y[1,])
[1] "2013-09-02" "2013-09-03" "2013-09-04" "2013-09-05" "2013-09-06"
[6] "2013-09-07" "2013-09-08"

Upvotes: 6

Richie Cotton
Richie Cotton

Reputation: 121067

That's just a weird behaviour of matrix. Dates are internally stored as an integer of the number of days since 1st Jan 1970. Those are the numbers that you are seeing.

Probably the best option is to store them in a data frame instead.

FYI, you can create a sequence of dates using seq.

x <- seq(as.Date("2013-09-02"), length.out = 140, by = "1 day")

Upvotes: 1

Related Questions