bic ton
bic ton

Reputation: 1408

How to deal with one column of two formats and single class?

I have one column with two different formats but the same class 'factor'.

D$date
2009-05-12 11:30:00
2009-05-13 11:30:00
2009-05-14 11:30:00
2009-05-15 11:30:00
42115.652
2876
8765

class(D$date)
factor

What I need is to convert the number to date.

D$date <- as.character(D$date)
D$date=ifelse(!is.na(as.numeric(D$date)), 
             as.POSIXct(as.numeric(D$date) * (60*60*24), origin="1899-12-30", tz="UTC"), 
             D$date)

Now the number was converted but to a strange number "1429630800".

I tried without ifelse:

as.POSIXct(as.numeric(42115.652) * (60*60*24), origin="1899-12-30", tz="UTC")
[1] "2015-04-21 15:38:52 UTC"

It was converted nicely.

Upvotes: 2

Views: 45

Answers (2)

Roman
Roman

Reputation: 17648

You can also create a function which transforms each value in POSIX, then using lapply and do.call.

b <- c("2009-05-12 11:30:00", "2009-05-13 11:30:00", "2009-05-14 11:30:00", 
       "2009-05-15 11:30:00", "42115.652", "2876", "8765")
foo <- function(x){
  if(!is.na(as.numeric(x))){
    as.POSIXct(as.numeric(x) * (60*60*24), origin="1899-12-30", tz="UTC") 
  }else{
    as.POSIXct(x, origin="1899-12-30", tz="UTC")
  }
}
do.call("c", lapply(b, foo))
[1] "2009-05-12 13:30:00 CEST" "2009-05-13 13:30:00 CEST" "2009-05-14 13:30:00 CEST" "2009-05-15 13:30:00 CEST"
[5] "2015-04-21 17:38:52 CEST" "1907-11-15 01:00:00 CET"  "1923-12-30 01:00:00 CET" 

Upvotes: 1

dww
dww

Reputation: 31452

The problem is that you are mixing up classes in the true/false halves of your ifelse. You can fix this by adding as.character like this

D$date = ifelse(!is.na(as.numeric(D$date)), 
           as.character(as.POSIXct(as.numeric(D$date) * (60*60*24), origin="1899-12-30", tz="UTC")), 
           D$date)

#D
#                 date
#1 2009-05-12 11:30:00
#2 2009-05-13 11:30:00
#3 2009-05-14 11:30:00
#4 2009-05-15 11:30:00
#5 2015-04-21 15:38:52
#6 1907-11-15 00:00:00
#7 1923-12-30 00:00:00

Upvotes: 3

Related Questions