Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does "^" on a data.frame return a matrix instead of a data.frame like "*" does?

Tags:

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).

like image 529
Arun Avatar asked Nov 13 '13 21:11

Arun


People also ask

Why would you use a matrix instead of a DataFrame type?

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.

Are matrix faster than data frame?

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.).

Can a data frame have a column that is a matrix?

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.


1 Answers

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.

like image 50
Neal Fultz Avatar answered Sep 25 '22 00:09

Neal Fultz