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.