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).
Both represent 'rectangular' data types, meaning that they are used to store tabular data, with rows and columns. The main difference, as you'll see, is that matrices can only contain a single class of data, while data frames can consist of many different classes of data.
However, because a column is a vector, it has to be a single data type. Matrices behave as two-dimensional vectors. They are faster to access and index than data frames, but less flexible in that every value in a matrix must be of the same data type (integer, numeric, character, etc.).
Similarly, every element of a matrix must be the same type; in a data frame, the different columns can have different types. You can make “list-array” by assigning dimensions to a list. You can make a matrix a column of a data frame with df$x <- matrix() , or using I() when creating a new data frame data.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With