3

I have a data frame with records from the month of October 2017. Column 6 has the dates as a character vector.

This is what it looks like:

> october2017[1:6,1:6]
        V1        V2 V3  V4    V5        V6
1 89108060 IN0000005 P2 RK1 CA1-R 10/1/2017
2 10503818 IN0000014 P2 RK1  CA31 10/2/2017
3 89108152 765000054 P2 RK1  CA31 10/3/2017
4 89108152 765000197 P2 RK1  CA31 10/4/2017
5 89108206 200000162 P2 RK1  CA31 10/5/2017
6 89108206 100001098 P2 RK1  CA31 10/6/2017
> class(october2017$V6)
[1] "character"

The actual data frame is much larger than this. What I want to do is create a new column to denote the day of the week that matches each date and add it to the data frame. If the date is "10/1/2017" I want the new column denoting the day of the week to show "Sunday" in that row.

This is what I want the data frame to look like:

> october2017[1:6,1:7]
        V1        V2 V3  V4    V5        V6     V7
1 89108060 IN0000005 P2 RK1 CA1-R 10/1/2017 Sunday
2 10503818 IN0000014 P2 RK1  CA31 10/2/2017 Monday
3 89108152 765000054 P2 RK1  CA31 10/3/2017 Tuesday
4 89108152 765000197 P2 RK1  CA31 10/4/2017 Wednesday
5 89108206 200000162 P2 RK1  CA31 10/5/2017 Thursday
6 89108206 100001098 P2 RK1  CA31 10/6/2017 Friday

This is what I tried: newcol = weekdays(as.Date(october2017$v6, format="%m/%d/%Y")) october2017 = cbind(october2017,newcol, stringsAsFactors=FALSE)

This is the error message I get when I try to run the first line of this code: Error in as.Date.default(october2017$v6, format = "%m/%d/%Y") : do not know how to convert 'october2017$v6' to class “Date”

Can anyone help me understand why this is happening?

Jennifer B.
  • 163
  • 1
  • 4
  • 10
  • 3
    Including a [minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) in your question will increase your chances of getting an answer. – Samuel Nov 10 '17 at 19:50
  • 1
    @Cedric, actually this still can work for factors, try `as.Date(factor("5/11/2017"), format='%m/%d/%Y')`, so it suggests `$v6` is something else. I second the vote for a MWE. – r2evans Nov 10 '17 at 21:02
  • @r2evans Thank you for checking, I've removed my comment about factor class. Jennifer check r2evans answer. – Cedric Nov 10 '17 at 21:38
  • @Cedric, I often make the same assumption and leap to that, and my habit is to rarely use factors (primarily for `ggplot` faceting, frankly). Every now and then I'm surprised when I accidentally have them and things still work as designed. Figure that. – r2evans Nov 10 '17 at 22:06
  • Yes thank you for your comment, `stacomirtools::killfactor()` is a bit of a joke but solved a lot of my problems.... – Cedric Nov 11 '17 at 06:53

2 Answers2

9

as.Date is a function that uses S3 method dispatch. That is, there are actually several functions:

methods("as.Date")
# [1] as.Date.character as.Date.date      as.Date.dates     as.Date.default  
# [5] as.Date.factor    as.Date.numeric   as.Date.POSIXct   as.Date.POSIXlt  
# see '?methods' for accessing help and source code

When you call as.Date(x), R looks at the class of the first object and uses the appropriate S3 method. If none is found and a .default function exists, then that will be used as a "last resort".

If you look at the source for each of the methods, you will only find the string "do not know how to convert" in as.Date.default:

as.Date.default
# function (x, ...) 
# {
#     if (inherits(x, "Date")) 
#         return(x)
#     if (is.logical(x) && all(is.na(x))) 
#         return(structure(as.numeric(x), class = "Date"))
#     stop(gettextf("do not know how to convert '%s' to class %s", 
#         deparse(substitute(x)), dQuote("Date")), domain = NA)
# }

If it were one of the known classes (character, date, dates, factor, numeric, POSIXct, or POSIXlt, and now also not Date or logical-NA), then it would have run the specific function instead (none of which include that error string). This suggests that your $v6 column is a different class. Without an MWE, it is complete speculation.

I suggest you find the actual class of your data

class(dataFrame$v6)

and figure out how to convert it to one of the known versions.

Edit

Furthermore, note that R is case-sensitive. Your MWE uses lower-case v6 but your column names are upper-case. How about just

october2017$V7 <- weekdays(as.Date(oct$V6, format="%m/%d/%Y"))

When you look at october2017$v6 (lower-case), it returns NULL, which triggers the .default method of as.Date.

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • Any thoughts or comments, Jennifer? – r2evans Nov 10 '17 at 23:42
  • dataFrame$v6 is a character vector composed of strings that look like this: "10/1/2017" "10/2/2017" "10/3/2017" "10/4/2017" "10/5/2017" "10/6/2017" etc. What I want to do is change them from strings to what R will recognize as dates. I thought that was what the as.Date function was supposed to do??!!! But if as.Date won't work then what will? – Jennifer B. Nov 13 '17 at 19:16
  • Jennifer, I really cannot know without seeing more. I cannot just reach through StackOverflow and see data on your computer, you need to edit your question and *give me something to work with*. jsb's suggested link is a good one, as is https://stackoverflow.com/help/mcve. So please read one or both of those links, then edit your question adding a minimal working example showcasing your difficulty. – r2evans Nov 13 '17 at 19:56
  • My apologies for not including an MWE. I'm now to Stack Overflow. I rewrote the question for you. Can you reproduce my MWE? – Jennifer B. Nov 14 '17 at 01:13
  • Thank you r2evans. I changed the name of the column from v6/V6, whichever it was, to Delivery.Date and then october2017$V7 <- weekdays(as.Date(oct$Delivery.Date, format="%m/%d/%Y")) worked perfectly. – Jennifer B. Nov 14 '17 at 23:38
  • So ... it worked? Great! (Can you "accept" the answer? There's a checkmark to the left of this answer.) – r2evans Nov 14 '17 at 23:40
0

This is several years after the fact, but I wanted to add the alternative method I used to get around this error.

First I pulled the character vector containing the dates into a new vector, then converted it to a 1-column dataframe containing a date class vector. From there I could overwrite the original column in my date.

dates <- data$date.column
dates <- data.frame(as.Date(dates, format = "%Y-%m-%d"))
data$date.column <- dates

I'm not entirely sure why it's necessary to wrap the as.Date() call in data.frame() in the middle step, but I found that it failed without it.

Hope it helps!