[R] Product of certain rows in a matrix
arun
smartpink111 at yahoo.com
Mon Sep 2 21:57:10 CEST 2013
Hi,
Make sure you check the class of the columns. I forgot about that.
str(mat1)
int [1:100000, 1:3] 1 2 10 18 2 16 1 18 12 19 ...
Convert it to numeric.
mat1New<- sapply(split(mat1,col(mat1)),as.numeric)
n<- 40
nrow(mat1New)%%40
#[1] 0
system.time({
j40<- n*seq_len(nrow(mat1New)/n)
vec1<- rep("j40",n)
res<- eval(parse(text= paste(paste0("mat1New","[",paste0(vec1,"-",seq(n)-1),",]"),collapse="*")
))
})
#user system elapsed
# 0.004 0.000 0.004
system.time({
j <- seq_len(nrow(mat1New))%%n
b <- mat1New[j==0,]
for(i in seq_len(n-1))b <- b*mat1New[j==i,]
})
# user system elapsed
# 0.112 0.000 0.116
all.equal(b,res)
#[1] TRUE
#if
nrow(mat1New)%%n!=0
For example:
n<- 22
nrow(mat1New)%%n
#[1] 10
system.time({
mat2<-mat1New[seq(nrow(mat1New)-10),]
j22<- n*seq_len(nrow(mat2)/n)
vec1<- rep("j22",n)
res<- eval(parse(text= paste(paste0("mat2","[",paste0(vec1,"-",seq(n)-1),",]"),collapse="*")
))
resNew<-rbind(res,apply(tail(mat1New,10),2,prod)
)})
# user system elapsed
# 0.008 0.000 0.007
A.K.
----- Original Message -----
From: arun <smartpink111 at yahoo.com>
To: Edouard Hardy <hardy.edouard at gmail.com>
Cc: Bert Gunter <gunter.berton at gene.com>
Sent: Monday, September 2, 2013 3:31 PM
Subject: Re: [R] Product of certain rows in a matrix
There was a slight mistake in the end:
I repeated vec1. But, it doesn't matter as the warning messages are the same.
j40<- n*seq_len(nrow(mat1)/n)
vec1<- rep("j40",n)
res<- eval(parse(text= paste(paste0("mat1","[",paste0(vec1,"-",seq(n)-1),",]"),collapse="*")
))
Warning messages:
1: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
NAs produced by integer overflow
2: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
NAs produced by integer overflow
3: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
NAs produced by integer overflow
4: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
NAs produced by integer overflow
5: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
NAs produced by integer overflow
6: In mat1[j40 - 0, ] * mat1[j40 - 1, ] * mat1[j40 - 2, ] * mat1[j40 - :
----- Original Message -----
From: arun <smartpink111 at yahoo.com>
To: Edouard Hardy <hardy.edouard at gmail.com>
Cc: R help <r-help at r-project.org>; Bert Gunter <gunter.berton at gene.com>
Sent: Monday, September 2, 2013 3:25 PM
Subject: Re: [R] Product of certain rows in a matrix
Hi,
You can try this:
n<- 3
j3<-n*seq_len(nrow(A)/n)
vec1<- rep("j3",n)
eval(parse(text=paste0("A","[",paste0(vec1,"-",seq(n)-1),",]",collapse="*")))
# [,1] [,2] [,3]
#[1,] 28 80 162
#[2,] 162 80 28
Just saw Bert's new solution:
n<-3
j <- seq_len(nrow(A))%%n
b <- A[j==0,]
for(i in seq_len(n-1))b <- b*A[j==i,]
b
# [,1] [,2] [,3]
#[1,] 28 80 162
#[2,] 162 80 28
#For the bigger dataset with large "n, these methods may not work:
set.seed(28)
mat1<- matrix(sample(1:20,1e5*3,replace=TRUE),ncol=3)
n<- 40
nrow(mat1)%%40
#[1] 0
j <- seq_len(nrow(mat1))%%n
b <- mat1[j==0,]
for(i in seq_len(n-1))b <- b*mat1[j==i,]
Warning messages:
1: In b * mat1[j == i, ] : NAs produced by integer overflow
2: In b * mat1[j == i, ] : NAs produced by integer overflow
3: In b * mat1[j == i, ] : NAs produced by integer overflow
4: In b * mat1[j == i, ] : NAs produced by integer overflow
5: In b * mat1[j == i, ] : NAs produced by integer overflow
6: In b * mat1[j == i, ] : NAs produced by integer overflow
7: In b * mat1[j == i, ] : NAs produced by integer overflow
8: In b * mat1[j == i, ] : NAs produced by integer overflow
9: In b * mat1[j == i, ] : NAs produced by integer overflow
10: In b * mat1[j == i, ] : NAs produced by integer overflow
head(b,3)
# [,1] [,2] [,3]
#[1,] NA NA NA
#[2,] NA NA NA
#[3,] NA NA NA
j40<- n*seq_len(nrow(mat1)/n)
vec1<- rep("j40",n)
vec1<- rep("j22",n)
res<- eval(parse(text= paste(paste0("mat1","[",paste0(vec1,"-",seq(n)-1),",]"),collapse="*")
))
Warning messages:
1: In mat1[j22 - 0, ] * mat1[j22 - 1, ] * mat1[j22 - 2, ] * mat1[j22 - :
NAs produced by integer overflow
2: In mat1[j22 - 0, ] * mat1[j22 - 1, ] * mat1[j22 - 2, ] * mat1[j22 - :
NAs produced by integer overflow
3: In mat1[j22 - 0, ] * mat1[j22 - 1, ] * mat1[j22 - 2, ] * mat1[j22 - :
NAs produced by integer overflow
4: In mat1[j22 - 0, ] * mat1[j22 - 1, ] * mat1[j22 - 2, ] * mat1[j22 - :
head(res,3)
# [,1] [,2] [,3]
#[1,] NA NA NA
#[2,] NA NA NA
#[3,] NA NA NA
A.K.
________________________________
From: Edouard Hardy <hardy.edouard at gmail.com>
To: arun <smartpink111 at yahoo.com>
Sent: Monday, September 2, 2013 2:32 PM
Subject: Re: [R] Product of certain rows in a matrix
Yes, n is 250 or more...
Edouard Hardy
On Mon, Sep 2, 2013 at 8:31 PM, arun <smartpink111 at yahoo.com> wrote:
Also, BTW, are you looking for n>100?
>
>
>
>
>
>
On Mon, Sep 2, 2013 at 8:27 PM, arun <smartpink111 at yahoo.com> wrote:
>
>Hi,
>
>Not sure I understand your question. If you don't know "n", then how are you applying other solutions also..
>A.K.
>
>
>
>Again, thank you for your help.
>
>I understand Bert's solution but this is possible only if I know n.
>
>How can I do A[j3,]*A[j3-1,]*A[j3-2,] (n=3) for n terms ?
>
>
>
>----- Original Message -----
>From: arun <smartpink111 at yahoo.com>
>To: Edouard Hardy <hardy.edouard at gmail.com>
>Cc: R help <r-help at r-project.org>; Bert Gunter <gunter.berton at gene.com>
>
>Sent: Monday, September 2, 2013 1:57 PM
>Subject: Re: [R] Product of certain rows in a matrix
>
>HI,
>You could modify Bert's solution:
>n<-3
>
>j3<-n*seq_len(nrow(A)/n)
>A[j3,]*A[j3-1,]*A[j3-2,] ##assuming that nrow(dataset)%%n==0
># [,1] [,2] [,3]
>#[1,] 28 80 162
>#[2,] 162 80 28
>
>
>#Speed comparison
>
>
>set.seed(28)
>mat1<- matrix(sample(1:20,1e5*3,replace=TRUE),ncol=3)
>
>n<-4
>system.time({res1<- t(sapply(split(as.data.frame(mat1),as.numeric(gl(nrow(mat1),n,nrow(mat1)))),function(x) apply(x,2,prod))) })
># user system elapsed
># 8.508 0.620 9.146
>system.time({res2<- t(sapply(split(as.data.frame(mat1),as.numeric(gl(nrow(mat1),n,nrow(mat1)))),function(x) Reduce("*",as.data.frame(t(x))))) })
># user system elapsed
># 8.556 0.000 8.566
>
>A1<- data.frame(mat1,ID=as.numeric(gl(nrow(mat1),n,nrow(mat1))))
> system.time({res3<- aggregate(A1[,-4],list(A1[,4]),colProds)[,-1]})
># user system elapsed
># 11.536 0.000 11.553
>
>
>nrow(mat1)%%n
>#[1] 0
>system.time({j4<- n*seq_len(nrow(mat1)/n)
> res5<- mat1[j4,]*mat1[j4-1,]*mat1[j4-2,]*mat1[j4-3,]
> })
>
># user system elapsed
># 0.004 0.000 0.004
>
> dimnames(res2)<- dimnames(res5)
>identical(res2,res5)
>#[1] TRUE
>
>
>#if
>n<-6
> nrow(mat1)%%6
>#[1] 4
>
>
>system.time({
> mat2<-mat1[seq(nrow(mat1)-4),]
>j6<- n*seq_len(nrow(mat2)/n)
> res6<- mat2[j6,]*mat2[j6-1,]*mat2[j6-2,]*mat2[j6-3,]*mat2[j6-4,]*mat2[j6-5,]
>res6New<-rbind(res6,apply(tail(mat1,4),2,prod)
>)})
>
># user system elapsed
> # 0.004 0.000 0.006
>
>
>
>system.time({res6Alt<-
>t(sapply(split(as.data.frame(mat1),as.numeric(gl(nrow(mat1),n,nrow(mat1)))),function(x) Reduce("*",as.data.frame(t(x))))) })
>#user system elapsed
> # 5.576 0.000 5.583
>dimnames(res6Alt)<- dimnames(res6New)
>
>
>all.equal(res6New,res6Alt)
>#[1] TRUE
>
>
>A.K.
>
>
>
>As you said, this is very loooong.
>Do you have a better solution on big data ?
>
>
>
>----- Original Message -----
>From: arun <smartpink111 at yahoo.com>
>To: Edouard Hardy <hardy.edouard at gmail.com>
>Cc: R help <r-help at r-project.org>; Bert Gunter <gunter.berton at gene.com>
>Sent: Monday, September 2, 2013 12:07 PM
>Subject: Re: [R] Product of certain rows in a matrix
>
>
>
>Hi,
>No problem.
>n<- 4
>
>t(sapply(split(as.data.frame(Anew),as.numeric(gl(nrow(Anew),n,nrow(Anew)))),function(x) apply(x,2,prod)))
>
># V1 V2 V3
>#1 252 640 1134
>#2 18 30 20
>
>
>This could be a bit slow if you have big dataset.
>
>
>A.K.
>
>
>
>________________________________
>From: Edouard Hardy <hardy.edouard at gmail.com>
>To: arun <smartpink111 at yahoo.com>
>Cc: R help <r-help at r-project.org>
>Sent: Monday, September 2, 2013 11:58 AM
>Subject: Re: [R] Product of certain rows in a matrix
>
>
>
>Thank you A.K.
>And do you have a solution without installing any package ?
>Thank you in advance.
>E.H.
>
>
>
>Edouard Hardy
>
>
>
>On Mon, Sep 2, 2013 at 5:56 PM, arun <smartpink111 at yahoo.com> wrote:
>
>
>>
>>HI,
>>In my first solutions:
>> n<-3
>> t(sapply(split(as.data.frame(Anew),as.numeric(gl(nrow(Anew),n,nrow(Anew)))),colProds))
>># [,1] [,2] [,3]
>>#1 28 80 162
>>#2 162 80 28
>>#3 1 3 5
>> n<-4
>> t(sapply(split(as.data.frame(Anew),as.numeric(gl(nrow(Anew),n,nrow(Anew)))),colProds))
>># [,1] [,2] [,3]
>>#1 252 640 1134
>>#2 18 30 20
>>
>>A.K.
>>
>>________________________________
>>From: Edouard Hardy <hardy.edouard at gmail.com>
>>To: arun <smartpink111 at yahoo.com>
>>Cc: Bert Gunter <gunter.berton at gene.com>; R help <r-help at r-project.org>
>>Sent: Monday, September 2, 2013 11:46 AM
>>
>>Subject: Re: [R] Product of certain rows in a matrix
>>
>>
>>
>>Thank you all for your responses.
>>The real problem is that all your answer work for products 2 by 2.
>>I now have to do the product n by n row.
>>Do you have a solution ?
>>Thank you in advance,
>>E.H.
>>
>>
>>
>>Edouard Hardy
>>
>>
>>
>>On Mon, Sep 2, 2013 at 5:43 PM, arun <smartpink111 at yahoo.com> wrote:
>>
>>I guess in such situations,
>>>
>>>
>>>fun1<- function(mat){
>>> if(nrow(mat)%%2==0){
>>> j<- 2*seq_len(nrow(mat)/2)
>>> b<- mat[j,]* mat[j-1,]
>>> }
>>> else {mat1<- mat[-nrow(mat),]
>>> j<- 2*seq_len(nrow(mat1)/2)
>>> b<- rbind(mat1[j,]*mat1[j-1,],mat[nrow(mat),])
>>> }
>>>b
>>>}
>>>fun1(A)
>>># [,1] [,2] [,3]
>>>
>>>#[1,] 4 10 18
>>>#[2,] 63 64 63
>>>#[3,] 18 10 4
>>> fun1(Anew)
>>># [,1] [,2] [,3]
>>>
>>>#[1,] 4 10 18
>>>#[2,] 63 64 63
>>>#[3,] 18 10 4
>>>#[4,] 1 3 5
>>>
>>>
>>>A.K.
>>>
>>>
>>>
>>>
>>>----- Original Message -----
>>>From: arun <smartpink111 at yahoo.com>
>>>To: Bert Gunter <gunter.berton at gene.com>
>>>Cc: R help <r-help at r-project.org>
>>>
>>>Sent: Monday, September 2, 2013 11:26 AM
>>>Subject: Re: [R] Product of certain rows in a matrix
>>>
>>>Hi Bert,
>>>Thanks. It is a better solution.
>>>
>>>If nrow() is not even.
>>>
>>>Anew<- rbind(A,c(1,3,5))
>>>j<-seq_len(nrow(Anew)/2)###
>>> Anew[j,]*Anew[j-1,]
>>>#Error in Anew[j, ] * Anew[j - 1, ] : non-conformable arrays
>>>
>>>t(sapply(split(as.data.frame(Anew),as.numeric(gl(nrow(Anew),2,7))),colProds))
>>> [,1] [,2] [,3]
>>>1 4 10 18
>>>2 63 64 63
>>>3 18 10 4
>>>4 1 3 5
>>>
>>>A.K.
>>>
>>>
>>>
>>>
>>>
>>>
>>>________________________________
>>>From: Bert Gunter <gunter.berton at gene.com>
>>>To: arun <smartpink111 at yahoo.com>
>>>Cc: R help <r-help at r-project.org>
>>>Sent: Monday, September 2, 2013 10:55 AM
>>>Subject: Re: [R] Product of certain rows in a matrix
>>>
>>>
>>>
>>>These elaborate manipulations are unnecessary and inefficient. Use indexing instead:
>>>
>>>j <- 2*seq_len(nrow(A)/2)
>>>b <- A[j,]*A[j-1,]
>>>b
>>>[,1] [,2] [,3]
>>>[1,] 4 10 18
>>>[2,] 63 64 63
>>>[3,] 18 10 4
>>>
>>>[,1] [,2] [,3]
>>>[1,] 4 10 18
>>>[2,] 63 64 63
>>>[3,] 18 10 4
>>>[,1] [,2] [,3]
>>>[1,] 4 10 18
>>>[2,] 63 64 63
>>>[3,] 18 10 4[,1] [,2] [,3]
>>>[1,] 4 10 18
>>>[2,] 63 64 63
>>>[3,] 18 10 4
>>>[,1] [,2] [,3]
>>>[1,] 4 10 18
>>>[2,] 63 64 63
>>>[3,] 18 10 4
>>>
>>>
>>>
>>>
>>>
>>>On Mon, Sep 2, 2013 at 7:25 AM, arun <smartpink111 at yahoo.com> wrote:
>>>
>>>Hi,
>>>>You could try:
>>>>
>>>>A<- matrix(unlist(read.table(text="
>>>>1 2 3
>>>>4 5 6
>>>>7 8 9
>>>>9 8 7
>>>>6 5 4
>>>>3 2 1
>>>>",sep="",header=FALSE)),ncol=3,byrow=FALSE,dimnames=NULL)
>>>>
>>>>library(matrixStats)
>>>> res1<-t(sapply(split(as.data.frame(A),as.numeric(gl(nrow(A),2,6))),colProds))
>>>> res1
>>>># [,1] [,2] [,3]
>>>>#1 4 10 18
>>>>#2 63 64 63
>>>>#3 18 10 4
>>>>
>>>>
>>>> res2<-t(sapply(split(as.data.frame(A),((seq_len(nrow(A))-1)%/%2)+1),colProds))
>>>> identical(res1,res2)
>>>>#[1] TRUE
>>>>
>>>>#or
>>>> t(sapply(split(as.data.frame(A),as.numeric(gl(nrow(A),2,6))),function(x) apply(x,2,prod)))
>>>>
>>>>#or
>>>>library(plyr)
>>>> as.matrix(ddply(as.data.frame(A),.(as.numeric(gl(nrow(A),2,6))),colProds)[,-1])
>>>># V1 V2 V3
>>>>#[1,] 4 10 18
>>>>#[2,] 63 64 63
>>>>#[3,] 18 10 4
>>>>
>>>>#or
>>>>do.call(rbind,tapply(seq_len(nrow(A)),list(as.numeric(gl(nrow(A),2,6))),FUN=function(x) colProds(A[x,])))
>>>>#or
>>>>A1<- data.frame(A,ID=as.numeric(gl(nrow(At),2,6)))
>>>> aggregate(A1[,-4],list(A1[,4]),colProds)[,-1]
>>>># X1 X2 X3
>>>>#1 4 10 18
>>>>#2 63 64 63
>>>>#3 18 10 4
>>>>
>>>>#or
>>>>library(data.table)
>>>>At<- data.table(A1,key='ID')
>>>>subset(At[,lapply(.SD,colProds),by=ID],select=-1)
>>>># X1 X2 X3
>>>>#1: 4 10 18
>>>>#2: 63 64 63
>>>>#3: 18 10 4
>>>>
>>>>A.K.
>>>>
>>>>
>>>>
>>>>
>>>>Hello,
>>>>
>>>>I have this matrix :
>>>>A =
>>>>1 2 3
>>>>4 5 6
>>>>7 8 9
>>>>9 8 7
>>>>6 5 4
>>>>3 2 1
>>>>
>>>>I would like to have this matrix (product of rows 2 by 2) :
>>>>A =
>>>>4 10 18
>>>>63 64 63
>>>>18 10 4
>>>>
>>>>Is it possible to do that without a loop ?
>>>>
>>>>Thank you in advance !
>>>>
>>>>______________________________________________
>>>>R-help at r-project.org mailing list
>>>>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.
>>>>
>>>
>>>
>>>--
>>>
>>>
>>>Bert Gunter
>>>Genentech Nonclinical Biostatistics
>>>
>>>Internal Contact Info:
>>>Phone: 467-7374
>>>Website:
>>>
>>>http://pharmadevelopment.roche.com/index/pdb/pdb-functional-groups/pdb-biostatistics/pdb-ncb-home.htm
>>>
>>>______________________________________________
>>>R-help at r-project.org mailing list
>>>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.
>>>
>>
>
More information about the R-help
mailing list