# [R] Multiply

Rui Barradas ru|pb@rr@d@@ @end|ng |rom @@po@pt
Fri Aug 4 20:12:22 CEST 2023

Às 19:03 de 04/08/2023, Val escreveu:
> Thank you,  Avi and Ivan.  Worked for this particular Example.
>
> Yes, I am looking for something with a more general purpose.
> I think Ivan's suggestion works for this.
>
> multiplication=as.matrix(dat1[,-1]) %*% as.matrix(dat2[match(dat1[,1],
> dat2[,1]),-1])
> Res=data.frame(ID = dat1[,1], Index = multiplication)
>
> On Fri, Aug 4, 2023 at 10:59 AM <avi.e.gross using gmail.com> wrote:
>>
>> Val,
>>
>> 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
>>
>>
>> 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,
>>                           index1=result[,1],
>>                           index2=result[,2])
>>
>>
>>> 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)
>>
>>   A,  0.25, 0.35
>>   B,  0.42, 0.52
>>
>> 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
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
> ______________________________________________
> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> and provide commented, minimal, self-contained, reproducible code.
Hello,

Slightly simpler:

multiplication <- as.matrix(dat1[,-1]) %*%
as.matrix(dat2[match(dat1[,1], dat2[,1]),-1])
Res <- data.frame(ID = dat1[,1], Index = multiplication)

# this is what I find simpler
# the method being called is cbind.data.frame
Res2 <- cbind(dat1[1], Index = multiplication)

identical(Res, Res2)
#> [1] TRUE

Hope this helps,