vagabond
vagabond

Reputation: 3594

Multiply a data frame column with a single row in another data frame, R

What is the best way to multiply each element of a column with each values in row of another data.frame?

I want to multiply df1[ ,1] with df2[1, ] and create df3 of dimension 5 rows x 5 columns.

df1 <- data.frame(V1 = c(10, 20, 30, 40, 50), V2=c(5, 10, 15, 20, 25))
> df1  
  V1 V2
1 10  5
2 20 10
3 30 15
4 40 20
5 50 25

df2 <- data.frame(Albany=0.5, Birmingham=1.0, Tuscany=1.5, 
                  NewYork = 2, Atlanta = 2.5, Alabama = 3)  

> df2  
  Albany Birmingham Tuscany NewYork Atlanta Alabama
1    0.5          1     1.5       2     2.5       3

The output should have one column for each place and five rows like this:

  Albany Birmingham Tuscany NewYork Atlanta Alabama
1      5         10      15      20      25      30
2     10         20      30      40      50      60
3     15         30      45      60      75      90
4     20         40      60      80     100     120
5     25         50      75     100     125     150

In my real data set, df1 has 9500 rows and df2 has 210 columns. So the output data frame I am looking for is nrow(9500) x ncol(210)

Upvotes: 0

Views: 2964

Answers (2)

Jota
Jota

Reputation: 17611

You can use

df1[,1] %o% t(df2)  ## same as  outer(df1[,1], t(df2), "*")
#, , 1
#
#     Albany Birmingham Tuscany NewYork Atlanta Alabama
#[1,]      5         10      15      20      25      30
#[2,]     10         20      30      40      50      60
#[3,]     15         30      45      60      75      90
#[4,]     20         40      60      80     100     120
#[5,]     25         50      75     100     125     150

To get a matrix directly use this:

(df1[,1] %o% t(df2))[,,1]

Upvotes: 2

Roland
Roland

Reputation: 132576

Subsetting rows of a data.frame returns a data.frame. Thus, you need to unlist it to get a vector:

df1[,1] %*% t(unlist(df2[1,]))
#     Albany Birmingham Tuscany NewYork Atlanta Alabama
#[1,]      5         10      15      20      25      30
#[2,]     10         20      30      40      50      60
#[3,]     15         30      45      60      75      90
#[4,]     20         40      60      80     100     120
#[5,]     25         50      75     100     125     150

Upvotes: 4

Related Questions