22

This question is motivated by a bug filed here by Abiel Reinhart on data.table. I noticed that the same happens on data.frame as well.

Here's an example:

DF <- data.frame(x=1:5, y=6:10)
> DF*DF
   x   y
1  1  36
2  4  49
3  9  64
4 16  81
5 25 100

> class(DF*DF) # [1] "data.frame"

> DF^2
      x   y
[1,]  1  36
[2,]  4  49
[3,]  9  64
[4,] 16  81
[5,] 25 100

> class(DF^2) # [1] "matrix"

Why does "^" coerce it into a matrix? Any ideas? Note that ** is converted to ^ by the parser. So, doing DF**2 would give the same result as DF^2.

I don't find anything related to this coercion in ?`^`.

Edit: Neal's answer shows clearly the reason for ^ returning a matrix when operated on a data.frame. It'd be great if the question as to why ^ is being left out in that piece of code could be answered as well.

Edit 2: I also posted here on R-help and got a reply from Duncan that there seems to be no info reg. this change in the NEWS (admittedly, it's a quite old change as Joshua and Duncan also pointed out).

rlue
  • 3
  • 2
Arun
  • 116,683
  • 26
  • 284
  • 387

1 Answers1

22

Ops.data.frame implements the math operators for data frames as S3 generics, here is the last couple lines:

if (.Generic %in% c("+", "-", "*", "/", "%%", "%/%")) {
    names(value) <- cn
    data.frame(value, row.names = rn, check.names = FALSE, 
        check.rows = FALSE)
}
else matrix(unlist(value, recursive = FALSE, use.names = FALSE), 
    nrow = nr, dimnames = list(rn, cn))

So ^ gets returned as a matrix.

Neal Fultz
  • 9,282
  • 1
  • 39
  • 60
  • 4
    :) Great. Very nice find! Now any idea why `^` is missed out there?? – Arun Nov 13 '13 at 21:46
  • 7
    It looks like that line was written in R 2.2.0 back in the day, according to [this repo](https://github.com/SurajGupta/r-source/blame/master/src/library/base/R/dataframe.R#L1528), so I would chalk it up to 'legacy behavior'. – Neal Fultz Nov 13 '13 at 21:57
  • 1
    You can easily redefine `Ops.data.frame` to include `"^"` in the vector of permissible functions. It will return a `data.frame` with correct results, but I am sure R-Core will have a (good?) reason as to why it is not there in the first place. Perhaps this one should be put to either r-help or r-devel. – Simon O'Hanlon Nov 13 '13 at 22:05
  • 3
    That line has existed in roughly that form since revision 3475 on 1999-01-29. If it was a mistake, I seriously doubt you could change it now without breaking things. – Joshua Ulrich Nov 13 '13 at 22:23
  • @Arun are you gonna ask why it is so on one of the *real* mailing lists? I'd be interested to know the response. – Simon O'Hanlon Nov 13 '13 at 22:41
  • @Arun the honour of a possible flame roast is yours. – Simon O'Hanlon Nov 13 '13 at 22:47