Multiplication (and R data types)

July 28, 2016
By

(This article was first published on The Practical R, and kindly contributed to R-bloggers)

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.

To leave a comment for the author, please follow the link and comment on their blog: The Practical R.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Sponsors

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)