Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
This is a basic post about multiplication operations in R. We’re considering element-wise multiplication versus matrix multiplication. First let’s make some data:
# Make some data a = c(1,2,3) b = c(2,4,6) c = cbind(a,b) x = c(2,2,2)
If we look at the output (c and x), we can see that c is a 3×2 matrix and x is a 1×3 matrix (which I will also call a vector).
# View our data c ## a b ## [1,] 1 2 ## [2,] 2 4 ## [3,] 3 6 x ## [1] 2 2 2
In R the asterisk (*) is used for element-wise multiplication. This is where the elements in the same row are multiplied by one another.
#These will give the same result c*x x*c
We can see that the output of c*x and x*c are the same, and the vector x doubles matrix c.
#View our element-wise multiplication output ## a b ## [1,] 2 4 ## [2,] 4 8 ## [3,] 6 12 ## a b ## [1,] 2 4 ## [2,] 4 8 ## [3,] 6 12
In R percent signs combined with asterisks are used for matrix multiplication (%*%).
# This works (matrix multiplication) x%*%c ## a b ## [1,] 12 24
If you dig back and remember your matrix multiplication, you’ll find that a 1×3 matrix times a 3×2 matrix gives a 1×2 matrix. It will have the same number of rows as the first matrix (x has 1 row) and the same number of columns as the second matrix (c has 2 columns). Now let’s try this with x and c reversed.
# This doesn't work. Incorrect dimensions. c%*%x ## Error in c %*% x : non-conformable arguments
R gives us an error because you can’t multiply a 3×2 and 1×3 matrix. For the matrix multiplication to work, the number of columns in the first matrix (c = 3 columns) has to be equal to the number of rows in the second matrix (x= 1 row).
The previous operations were done using the default R arrays, which are matrices. We can confirm this using the command class and typeof below:
# Get the data type class(c) typeof(c) class(x) typeof(x)
Here’s the output of those functions.
# The output ## [1] "matrix" ## [1] "double" ## [1] "numeric" ## [1] "double"
This shows us that our matrix c, has the R data type of a matrix, with formatting of ‘double’, which means that is is numbers (as opposed to something like ‘character’). This also shows us our 1×3 matrix or vector has the R data type ‘numeric’ and also has the formatting of ‘double’.
Now, let’s say your data is in a data frame rather than a matrix. Let’s see what happens when we perform multiplication on data frames. Remember data frames in R can hold different types of data (numbers, letters, etc.), while matrices can only have one type of data.
***For more info about this see my post here titled CBIND2***
Let’s convert our matrices to data frames using the function data.frame.
c1 = data.frame(c) x1 = data.frame(x)
Now let’s look at our data. Note that there is an extra column of numbers from 1 to 3 for both c1 and x1. This is just a feature of the data frame output in R, where it is counting the rows 1 through 3.
c1 ## a b ## 1 1 2 ## 2 2 4 ## 3 3 6 x1 ## x ## 1 2 ## 2 2 ## 3 2
And just to be thorough, let’s check the R data type, to make sure they are not matrices.
# Check the data type class(c1) typeof(c1) class(x1) typeof(x1)
Here’s the output of those the data type. Notice that the class is now ‘data.frame’ instead of ‘matrix’ or ‘numeric’.
# The output ## [1] "data.frame" ## [1] "list" ## [1] "data.frame" ## [1] "list"
Now let’s try our simple element-wise multiplication again. You may have guessed it already, but these functions will no longer work.
# These both do not work c1*x1 x1*c1
Here’s the output of the multiplication (i.e., the errors R provides).
## Error in Ops.data.frame(c1, x1) : ## ‘*’ only defined for equally-sized data frames ## Error in Ops.data.frame(c1, x1) : ## ‘*’ only defined for equally-sized data frames
According to the error R is providing, we can only multiply data frames of the same size. So, let’s try this out by making some new data.
# Make some data h=c(2,2) k=c(4,4) j=cbind(h,k) l=j*2 df1 = data.frame(j) df2 = data.frame(l)
Now let’s look at the data to see what we have
# View the new data frames df1 ## h k ## 1 2 4 ## 2 2 4 df2 ## h k ## 1 4 8 ## 2 4 8
Finally, let’s multiply df1*df2 and see what happens.
# Data frame multiplication df1*df2 ## h k ## 1 8 32 ## 2 8 32
R has done element-wise multiplication on the data frames. This makes sense since we use only the (*) command. If we try this again with the order of the data frames reversed, we will get the same answer.
# Reverse the order for multiplication df2*df1 ## h k ## 1 8 32 ## 2 8 32
That’s all for now. Hopefully this shed more light onto the way R performs multiplication, especially based on the data type.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.