Arnaud Duranel
2012-Sep-24 08:06 UTC
[R] POSIXct coerced into numeric when filling a data frame
Hello
I have a list of POSIXct objects, from which I want to extract those
values that match a specific date, keeping them in POSIXct format. For a
specific date there is 0-2 matching values.
As an example (the actual list and objects are much longer):
x<-list()
x[["first"]]<-as.POSIXct(c("2011-08-27 10:45:00 GMT",
"2011-10-30
15:45:00 GMT", "2011-10-30 16:00:00 GMT", "2012-06-22
09:30:00 GMT"))
x[["second"]]<-as.POSIXct(c("2011-08-27 11:00:00 GMT",
"2011-10-30
15:30:00 GMT", "2011-10-30 15:45:00 GMT", "2012-06-22
10:00:00 GMT"))
If I use the following expression for one specific object of the list, I
get the result I expect:
x[[1]][as.Date(x[[1]])=="2011/10/30"][1]
[1] "2011-10-30 15:45:00 GMT"
Now if I write a for loop based on that expression to store the values
of interest in a data frame, the POSIXct values are coerced into numeric:
y<-data.frame()
for (i in 1:length(x)) {
y[i,"ID"]<-names(x[i])
y[i,"first"]<-x[[i]][as.Date(x[[i]])=="2011/10/30"][1]
y[i,"second"]<-x[[i]][as.Date(x[[i]])=="2011/10/30"][2]
}
ID first second
1 a 1319989500 1319990400
2 b 1319988600 1319989500
I am a bit confused about why that is.
I could coerce them back to POSIXct with another line of code, but is
there a better way? And is there a way to avoid using a for loop to
complete this task?
No need to say I am quite new to R, so apologies for any obvious mistake
or oversight.
Many thanks
A. Duranel, UCL Department of Geography
[[alternative HTML version deleted]]
HI,
Try this:
dat1<-do.call(data.frame,x)
dat1<-data.frame(ID=letters[1:4],dat1)
dat1
#? ID?????????????? first????????????? second
#1? a 2011-08-27 10:45:00 2011-08-27 11:00:00
#2? b 2011-10-30 15:45:00 2011-10-30 15:30:00
#3? c 2011-10-30 16:00:00 2011-10-30 15:45:00
#4? d 2012-06-22 09:30:00 2012-06-22 10:00:00
?str(dat1)
#'data.frame':??? 4 obs. of? 3 variables:
# $ ID??? : Factor w/ 4 levels
"a","b","c","d": 1 2 3 4
?#$ first : POSIXct, format: "2011-08-27 10:45:00" "2011-10-30
15:45:00" ...
?#$ second: POSIXct, format: "2011-08-27 11:00:00" "2011-10-30
15:30:00" ...
dat2<-dat1
?dat2$first<-as.Date(dat2$first,format="%Y-%m-%d %HH:MM:%SS")
?dat2$second<-as.Date(dat2$second,format="%Y-%m-%d %HH:MM:%SS")
?dat2
#? ID????? first???? second
#1? a 2011-08-27 2011-08-27
#2? b 2011-10-30 2011-10-30
#3? c 2011-10-30 2011-10-30
#4? d 2012-06-22 2012-06-22
?str(dat2)
#'data.frame':??? 4 obs. of? 3 variables:
# $ ID??? : Factor w/ 4 levels
"a","b","c","d": 1 2 3 4
# $ first : Date, format: "2011-08-27" "2011-10-30" ...
# $ second: Date, format: "2011-08-27" "2011-10-30" ...
dat2<-within(dat2,ID<-as.character(ID))
subset(dat2,ID%in% c("a","b"))
#? ID????? first???? second
#1? a 2011-08-27 2011-08-27
#2? b 2011-10-30 2011-10-30
A.K.
----- Original Message -----
From: Arnaud Duranel <arnaud.duranel.09 at ucl.ac.uk>
To: r-help at r-project.org
Cc:
Sent: Monday, September 24, 2012 4:06 AM
Subject: [R] POSIXct coerced into numeric when filling a data frame
Hello
I have a list of POSIXct objects, from which I want to extract those
values that match a specific date, keeping them in POSIXct format. For a
specific date there is 0-2 matching values.
As an example (the actual list and objects are much longer):
x<-list()
x[["first"]]<-as.POSIXct(c("2011-08-27 10:45:00 GMT",
"2011-10-30
15:45:00 GMT", "2011-10-30 16:00:00 GMT", "2012-06-22
09:30:00 GMT"))
x[["second"]]<-as.POSIXct(c("2011-08-27 11:00:00 GMT",
"2011-10-30
15:30:00 GMT", "2011-10-30 15:45:00 GMT", "2012-06-22
10:00:00 GMT"))
If I use the following expression for one specific object of the list, I
get the result I expect:
x[[1]][as.Date(x[[1]])=="2011/10/30"][1]
[1] "2011-10-30 15:45:00 GMT"
Now if I write a for loop based on that expression to store the values
of interest in a data frame, the POSIXct values are coerced into numeric:
y<-data.frame()
for (i in 1:length(x)) {
? y[i,"ID"]<-names(x[i])
? y[i,"first"]<-x[[i]][as.Date(x[[i]])=="2011/10/30"][1]
?
y[i,"second"]<-x[[i]][as.Date(x[[i]])=="2011/10/30"][2]
}
? ID? ? ? first? ? second
1? a 1319989500 1319990400
2? b 1319988600 1319989500
I am a bit confused about why that is.
I could coerce them back to POSIXct with another line of code, but is
there a better way? And is there a way to avoid using a for loop to
complete this task?
No need to say I am quite new to R, so apologies for any obvious mistake
or oversight.
Many thanks
A. Duranel, UCL Department of Geography
??? [[alternative HTML version deleted]]
______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.