[R] Multiply

@vi@e@gross m@iii@g oii gm@ii@com @vi@e@gross m@iii@g oii gm@ii@com
Fri Aug 4 17:59:16 CEST 2023


A data.frame is not quite the same thing as a matrix.

But as long as everything is numeric, you can convert both data.frames to
matrices, perform the computations needed and, if you want, convert it back
into a data.frame.

BUT it must be all numeric and you violate that requirement by having a
character column for ID. You need to eliminate that temporarily:

dat1 <- read.table(text="ID, x, y, z
 A, 10,  34, 12
 B, 25,  42, 18
 C, 14,  20,  8 ",sep=",",header=TRUE,stringsAsFactors=F)

mat1 <- as.matrix(dat1[,2:4])

The result is:

> mat1
      x  y  z
[1,] 10 34 12
[2,] 25 42 18
[3,] 14 20  8

Now do the second matrix, perhaps in one step:

mat2 <- as.matrix(read.table(text="ID, weight, weiht2
 A,  0.25, 0.35
 B,  0.42, 0.52
 C,  0.65, 0.75",sep=",",header=TRUE,stringsAsFactors=F)[,2:3])

Do note some people use read.csv() instead of read.table, albeit it simply
calls read.table after setting some parameters like the comma.

The result is what you asked for, including spelling weight wrong once.:

> mat2
     weight weiht2
[1,]   0.25   0.35
[2,]   0.42   0.52
[3,]   0.65   0.75

Now you wanted to multiply as in matrix multiplication.

> mat1 %*% mat2
     weight weiht2
[1,]  24.58  30.18
[2,]  35.59  44.09
[3,]  17.10  21.30

Of course, you wanted different names for the columns and you can do that
easily enough:

result <- mat1 %*% mat2

colnames(result) <- c("index1", "index2")

But this is missing something:

> result
     index1 index2
[1,]  24.58  30.18
[2,]  35.59  44.09
[3,]  17.10  21.30

Do you want a column of ID numbers on the left? If numeric, you can keep it
in a matrix in one of many ways but if you want to go back to the data.frame
format and re-use the ID numbers, there are again MANY ways. But note mixing
characters and numbers can inadvertently convert everything to characters.

Here is one solution. Not the only one nor the best one but reasonable:

recombined <- data.frame(index=dat1$ID, 

> recombined
  index index1 index2
1     A  24.58  30.18
2     B  35.59  44.09
3     C  17.10  21.30

If for some reason you need a more general purpose way to do this for
arbitrary conformant matrices, you can write a function that does this in a
more general way but perhaps a better idea might be a way to store your
matrices in files in a way that can be read back in directly or to not
include indices as character columns but as row names.

-----Original Message-----
From: R-help <r-help-bounces using r-project.org> On Behalf Of Val
Sent: Friday, August 4, 2023 10:54 AM
To: r-help using R-project.org (r-help using r-project.org) <r-help using r-project.org>
Subject: [R] Multiply

Hi all,

I want to multiply two  data frames as shown below,

dat1 <-read.table(text="ID, x, y, z
 A, 10,  34, 12
 B, 25,  42, 18
 C, 14,  20,  8 ",sep=",",header=TRUE,stringsAsFactors=F)

dat2 <-read.table(text="ID, weight, weiht2
 A,  0.25, 0.35
 B,  0.42, 0.52
 C,  0.65, 0.75",sep=",",header=TRUE,stringsAsFactors=F)

Desired result

ID  Index1 Index2
1  A 24.58 30.18
2  B 35.59 44.09
3  C 17.10 21.30

Here is my attempt,  but did not work

dat3 <- data.frame(ID = dat1[,1], Index = apply(dat1[,-1], 1, FUN=
function(x) {sum(x*dat2[,2:ncol(dat2)])} ), stringsAsFactors=F)

Any help?

Thank you,

R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

More information about the R-help mailing list