0

I have a column of factors that I want to convert to characters. (e.g. '18-DEC-15'). Calling df$dates and unique(df$dates) yields a typically diverse column of dates/factors, as expected.

Calling as.character(df$dates) yields the same list as df$dates, visually inspected from the console. However, calling ifelse(TRUE,as.character(df$dates),df$dates) yields only a single element - a single, arbitrary date.

I've no clue why wrapping a call in ifelse would change the underlying operation. Dplyr seems to solve this problem, as calling transmute(df,newvar=as.character(dates)) does produce the correct list, unlike the maddeningly simple ifelse(). This seems to be a huge argument in favor of mutate I've never heard before. Also, ifelse(FALSE,as.character(df$dates),df$dates) returns a single integer (~130) rather than the actual list of factors contained in df$dates

Edit - thanks for helpful comments. rep(T/F,nrow()) is precisely the right approach and explains why the first test failed (ie, it actually would have passed). The question is now the difference between ifelse(rep(TRUE,nrow(df)),as.character(df$dates),df$dates) and ifelse(rep(FALSE,nrow(df)),as.character(df$dates),df$dates). Obviously, making the correction, the FALSE test still fails. namely, it returns a vector of integers while the TRUE test returns the proper vector (one of readable dates)

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
3pitt
  • 899
  • 13
  • 21
  • 2
    The `?ifelse` help begins *"`ifelse` returns a value with the same shape as `test`..."*. If you give a `test` of length 1, like `TRUE` or `FALSE`, then the result will be of length 1. It's a vectorized version of `if(){} else{}`, vectorized over the test. – Gregor Thomas Oct 16 '17 at 16:25
  • @Gregor answer is correct. Try `ifelse` with a vector of `TRUE` with the same length as `df$dates`. – PhillipD Oct 16 '17 at 16:28
  • You could make your test of the same length, `ifelse(rep(TRUE, nrow(df)), as.character(df$dates), df$dates)`. Comparing `ifelse` to `mutate` is strange. mutate adds columns to a data frame, `ifelse` take a vector and, based on conditions, modifies each element individually. The base equivalent of `transmute(df,newvar=as.character(dates))` is simply `df$newvar = as.character(df$dates)`. – Gregor Thomas Oct 16 '17 at 16:28
  • `ifelse` would be useful if, for example, you wanted to add a year to all of your dates before some cutoff, e.g., `ifelse(df$dates < as.Date('2017-10-15'), df$dates + 365, df$dates)`. It is pointless to use it with an always true or always false condition. – Gregor Thomas Oct 16 '17 at 16:32
  • 2
    Voting to close as "unclear what you're asking", as it just seems to be general confusion about what `ifelse` is supposed to be. – Gregor Thomas Oct 16 '17 at 16:33
  • @gregor that's exactly right, if the first arg to ifelse() doesn't vary based on row number, then you should just wrap the operation in a normal if or if/then statement – 3pitt Oct 16 '17 at 16:38
  • Well, I can't change my close vote, but if that's the answer you were looking for I'd suggest closing as a duplicate of this old question: [Why can't `ifelse` return a vector?](https://stackoverflow.com/q/1335830/903061), the answers there cover the difference between `if` and `ifelse`. – Gregor Thomas Oct 16 '17 at 16:43
  • I think the question about why changing true to false makes all the dates turn into integers is pretty juicy. am I wrong, and if not should I still close this question? – 3pitt Oct 16 '17 at 16:47
  • I think I have seen 3 - 4 similar question about the behavior of `ifelse(test)` in the past few weeks. I think one thing that Hadley Wickham has done well is give informative errors. With the same data above, run `if_else()`. It will give you the right error to figure out why this code doesn't work. – jacobsg Oct 16 '17 at 20:35

0 Answers0