Multiplication (and R data types)

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
##      a b
## [1,] 1 2
## [2,] 2 4
## [3,] 3 6
## [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

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

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.

##   a b
## 1 1 2
## 2 2 4
## 3 3 6

##   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

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

Here’s the output of the multiplication (i.e., the errors R provides).

## Error in, x1) : 
##   ‘*’ only defined for equally-sized data frames

## Error in, 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

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
##   h k
## 1 2 4
## 2 2 4

##   h k
## 1 4 8
## 2 4 8

Finally, let’s multiply df1*df2 and see what happens.

# Data frame multiplication
##   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
##   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.

5 thoughts on “Multiplication (and R data types)

    • You cannot do matrix multiplication with data frames because they are class ‘data.frame’. If you try the %*% operator, it will give you an error. Matrix multiplication can only be completed with matrices – class ‘matrix’. Hope this helps!!!


  1. How can one make column-wise multiplications so that missing values are included (na.rm = TRUE)?
    I have tried (prod, v1, v2, na.rm = TRUE) which only gives me Inf as an answer for every single value.
    I’d be grateful for any further suggestions. Thank you.


    • If you were multiplying two values and one of them was NA, you would get NA as your answer. Ignoring NAs would provide little benefit. However, if you use a function like apply(), which allows you to sum or average across rows or columns, you can use the call na.rm=TRUE to ignore NAs. Hope this helps!


      • Actually, if you use the apply function then you can do this.
        apply(c, 1, prod, na.rm = TRUE),
        where “c” is the matrix, 1 performs the operation across rows, “prod” is the function for multiplication, and na.rm ignores NAs.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s