[See the end for an interesting twist on moving a column to row.names.]

Yes, many ways to do things exist but it may make sense to ask for what the 
user/OP really wants. Sometimes the effort to make a brief example obscures 
things.

Was there actually any need to read in a file containing comma-separated 
values? Did it have to include one, or perhaps more, non-numeric columns? Was 
the ID column guaranteed to exist and be named ID or just be the first column? 
Is any error checking needed?

So assuming we read in two data structures into data.frames called A and B to 
be unoriginal. A wider approach might be to split A into A.text and A.numeric 
by checking which columns test as numeric (meaning is.numeric() return TRUE) 
and which can be text or logical or anything else. Note that complex is not 
considered numeric if that matters.

You might then count the number of rows and columns of A.numeric and set A.text 
Aside for now. 

You then get B and it seems you can throw away any non-numeric columns. The 
resulting numeric columns can be in B.numeric.
The number of rows and columns of what remains need to conform to the 
dimensions of A in the sense that if a is M rows by N columns, then B must be N 
x anything and the result of the multiplication is M x anything. If the 
condition is not met, you need to fail gracefully.

You may also want to decide what to do with data that came with things like NA 
content. Or, if your design allows content that can be converted to numeric, 
check and make any conversions.

Then you can convert the data into matrices, perform the matrix multiplication 
and optionally restore any column names you want along with any of the 
non-numeric columns you held back and note there could possible be more than 
one. Obviously, getting multiple ones in the original order is harder.

I am not sure if you are interested in another tweak. For some purposes, 
rownames() and colnames() make sense instead of additional rows or columns.

A line of code like this applied to a data.frame will copy your id column as a 
rowname then remove the actual ID column.

> dat1
  ID  x  y  z
1  A 10 34 12
2  B 25 42 18
3  C 14 20  8
> rownames(dat1) <- dat1$ID
> dat1$ID <- NULL
> dat1
    x  y  z
 A 10 34 12
 B 25 42 18
 C 14 20  8

> result <- as.matrix(dat1) %*% mat2
> result
   weight weiht2
 A  24.58  30.18
 B  35.59  44.09
 C  17.10  21.30

There are functions (perhaps in packages, with names like column_to_rownames() 
in the tidyverse packages that can be used and you can also reverse the process.

Just some thoughts. The point is that it is often wiser to not mix text with 
numeric and rownames and colnames provide a way to include the text for the 
purposes you want and not for others where they are in the way. And here is an 
oddity I found:

> dat2
  ID weight weiht2
1  A   0.25   0.35
2  B   0.42   0.52
3  C   0.65   0.75
> temp <- data.frame(dat2, row.names=1)
> temp
   weight weiht2
 A   0.25   0.35
 B   0.42   0.52
 C   0.65   0.75

As shown, when you create a data.frame you can move any column by NUMBER into 
rownames. So consider your early code and note read.table supports the option 
row.names=1 and passes it on so in one step:

> ?read.table
> 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, row.names=1)
> dat1
   x  y  z
A 10 34 12
B 25 42 18
C 14 20  8

You can make it a matrix immediately:

mat1 <- as.matrix(read.table(
  text = text,
  sep = ",",
  header = TRUE,
  stringsAsFactors = F,
  row.names = 1
))


-----Original Message-----
From: Val <valkr...@gmail.com> 
Sent: Friday, August 4, 2023 2:03 PM
To: avi.e.gr...@gmail.com
Cc: r-help@r-project.org
Subject: Re: [R] Multiply

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.gr...@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
>  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,
>                          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-boun...@r-project.org> On Behalf Of Val
> Sent: Friday, August 4, 2023 10:54 AM
> To: r-help@R-project.org (r-help@r-project.org) <r-help@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@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to