ceba
ceba

Reputation: 77

Multiplying two dataframes in R

I have 2 data frames with 2 columns each and I would like to multiply each cell of column 2 from dataframe 1 with each cell of column 2 from dataframe 2. Also, I want that I should retain column 1 of both dataframes so that I know the multiplication is between which cells. My dataframe looks like

dataframe 1:

Text1  Value
ab      5
ak      6
bd      1

dataframe 2:

Text2  Value
acc     3
fnn     2

and I want output like this

Text1   Text2   Value
ab       acc      15
ab       fnn      10
ak       acc      18
ak       fnn      12
bd       acc       3
bd       fnn       2

Thanks in advance!

Upvotes: 1

Views: 432

Answers (3)

akrun
akrun

Reputation: 886938

Here is an option with data.table

library(data.table)
CJ(Text1 = df1[,1], Text2 = df2[,1])[, Value := c(outer(df2[,2], df1[,2]))][]
#   Text1 Text2 Value
#1:    ab   acc    15
#2:    ab   fnn    10
#3:    ak   acc    18
#4:    ak   fnn    12
#5:    bd   acc     3
#6:    bd   fnn     2

If column names are not an issue, above can be made more compact

CJ(df1[,1], df2[,1])[, value := c(df2[,2] %o% df1[,2])][]

Or an option using tidyverse

library(tidyverse)
df1 %>%
    mutate(new = list(df2)) %>%
    unnest %>% 
    transmute(Text1, Text2, value = Value * Value1)
#  Text1 Text2 value
#1    ab   acc    15
#2    ab   fnn    10
#3    ak   acc    18
#4    ak   fnn    12
#5    bd   acc     3
#6    bd   fnn     2

Upvotes: 1

Onyambu
Onyambu

Reputation: 79188

Using Base R:

transform(merge(cbind(dat1,id=1),cbind(dat2,id=1),by="id"),value=Value.x*Value.y,Value.x=NULL,Value.y=NULL,id=NULL)
  Text1 Text2 value
1    ab   acc    15
2    ab   fnn    10
3    ak   acc    18
4    ak   fnn    12
5    bd   acc     3
6    bd   fnn     2

using tidyverse

library(tidyverse)
dat1%>%
  mutate(id=1)%>%
  full_join(dat2%>%mutate(id=1),by="id")%>%
  mutate(value=Value.x*Value.y)%>%
  select(Text1,Text2,value)

  Text1 Text2 value
1    ab   acc    15
2    ab   fnn    10
3    ak   acc    18
4    ak   fnn    12
5    bd   acc     3
6    bd   fnn     2

another base R option

cbind(expand.grid(Text2=dat2$Text2,Text1=dat1$Text1),value=c(dat2$Value%o%dat1$Value))
  Text2 Text1 value
1   acc    ab    15
2   fnn    ab    10
3   acc    ak    18
4   fnn    ak    12
5   acc    bd     3
6   fnn    bd     2

Upvotes: 1

Rage
Rage

Reputation: 323

In case your dataframes retain the same structure as you have mentioned, the following function should do the trick for you.

df_multiply<-function(data1,data2){
  Text1<-Text2<-Value<-vector()
  for(i in 1:nrow(data1)){
    val1<-data1[[2]][i]
    for(j in 1:nrow(data2)){
      Text1<-c(Text1,as.character(data1[[1]][i]))
      Text2<-c(Text2,as.character(data2[[1]][j]))
      val2<-val1 * data2[[2]][j]
      Value<-c(Value,val2)
    }
  }
  res<-data.frame("Text1" = Text1,"Text2" = Text2,"Value" = Value)
  return(res)
}

To use the function, just use the names of your data frames as the input arguments. For example, df_multiply(data1 = dataframe1,data2 = dataframe2)
Hope that helps!

Upvotes: 0

Related Questions