Dear R community, I'm trying to remove a loop from my code but I'm stock and I can't find a good way to do it. Hopefully one of you will have something clever to propose. Here is a simplified example: I have a squared matrix:> nom.plac2 <- c("102", "103", "301", "303","304", "403") > poids2 <- matrix(NA, 6,6, dimnames=list(nom.plac2,nom.plac2)) > poids2102 103 301 303 304 403 102 NA NA NA NA NA NA 103 NA NA NA NA NA NA 301 NA NA NA NA NA NA 303 NA NA NA NA NA NA 304 NA NA NA NA NA NA 403 NA NA NA NA NA NA I want to replace some of the NAs following specific criterion included in 2 others matrix:> wei2 <- matrix(c(.6,.4,.5,.5,.9,.1,.8,.2,.7,.3,.6,.4),6,2,dimnames=list(nom.plac2, c("p1","p2")),byrow=T) > wei2p1 p2 102 0.6 0.4 103 0.5 0.5 301 0.9 0.1 303 0.8 0.2 304 0.7 0.3 403 0.6 0.4> voisin <- matrix(c("103","304", "303", "102", "103" ,"303","403","304","303","102","103" ,"303"),6,2,dimnames=list(nom.plac2, c("v1","v2")),byrow=T)> voisinv1 v2 102 "103" "304" 103 "303" "102" 301 "103" "303" 303 "403" "304" 304 "303" "102" 403 "103" "303" So my final result is: 102 103 301 303 304 403 102 NA 0.6 NA NA 0.4 NA 103 0.5 NA NA 0.5 NA NA 301 NA 0.9 NA 0.1 NA NA 303 NA NA NA NA 0.2 0.8 304 0.3 NA NA 0.7 NA NA 403 NA 0.6 NA 0.4 NA NA So, globally I want to fill for each line of "poids2" data from "wei2" associated with the good the good identifier found in "voisin". This can easily be done by a loop:> loop <- poids2 > for(i in 1:6){+ loop[i,voisin[i,]] <- wei2[i,] + } But I expect it to be quite slow with my larger dataset. Does any of you has an idea how I could remove the loop and speed up the operation? Best regards, Bastien Ferland-Raymond, M.Sc. Stat., M.Sc. Biol. Division des orientations et projets sp?ciaux Direction des inventaires forestiers Minist?re des Ressources naturelles et de la Faune du Qu?bec
try this:> nom.plac2 <- c("102", "103", "301", "303","304", "403") > poids2 <- matrix(NA, 6,6, dimnames=list(nom.plac2,nom.plac2)) > poids2102 103 301 303 304 403 102 NA NA NA NA NA NA 103 NA NA NA NA NA NA 301 NA NA NA NA NA NA 303 NA NA NA NA NA NA 304 NA NA NA NA NA NA 403 NA NA NA NA NA NA> wei2 <- matrix(c(.6,.4,.5,.5,.9,.1,.8,.2,.7,.3,.6,.4),6,2,dimnames=list(nom.plac2, c("p1","p2")),byrow=T) > voisin <- matrix(c("103","304", "303", "102", "103" ,"303","403","304","303","102","103" ,"303"),+ 6,2,dimnames=list(nom.plac2, c("v1","v2")),byrow=T)> > # do matrix addressing by converting names to numbers > indx <- rbind(+ cbind(match(rownames(voisin), rownames(poids2)) + , match(voisin[, 1], colnames(poids2)) + ) + , cbind(match(rownames(voisin), rownames(poids2)) + , match(voisin[, 2], colnames(poids2)) + ) + )> indx[,1] [,2] [1,] 1 2 [2,] 2 4 [3,] 3 2 [4,] 4 6 [5,] 5 4 [6,] 6 2 [7,] 1 5 [8,] 2 1 [9,] 3 4 [10,] 4 5 [11,] 5 1 [12,] 6 4> > # change the data > poids2[indx] <- c(wei2[,1], wei2[,2]) > poids2102 103 301 303 304 403 102 NA 0.6 NA NA 0.4 NA 103 0.5 NA NA 0.5 NA NA 301 NA 0.9 NA 0.1 NA NA 303 NA NA NA NA 0.2 0.8 304 0.3 NA NA 0.7 NA NA 403 NA 0.6 NA 0.4 NA NA> > >On Thu, Nov 3, 2011 at 1:25 PM, <Bastien.Ferland-Raymond at mrnf.gouv.qc.ca> wrote:> Dear R community, > > I'm trying to remove a loop from my code but I'm stock and I can't find a good way to do it. ?Hopefully one of you will have something clever to propose. > > Here is a simplified example: > > I have a squared matrix: > >> nom.plac2 <- c("102", "103", "301", "303","304", "403") >> poids2 <- matrix(NA, 6,6, dimnames=list(nom.plac2,nom.plac2)) >> poids2 > ? ?102 103 301 303 304 403 > 102 ?NA ?NA ?NA ?NA ?NA ?NA > 103 ?NA ?NA ?NA ?NA ?NA ?NA > 301 ?NA ?NA ?NA ?NA ?NA ?NA > 303 ?NA ?NA ?NA ?NA ?NA ?NA > 304 ?NA ?NA ?NA ?NA ?NA ?NA > 403 ?NA ?NA ?NA ?NA ?NA ?NA > > I want to replace some of the NAs following specific criterion included in 2 others matrix: > >> wei2 <- matrix(c(.6,.4,.5,.5,.9,.1,.8,.2,.7,.3,.6,.4),6,2,dimnames=list(nom.plac2, c("p1","p2")),byrow=T) >> wei2 > ? ? p1 ?p2 > 102 0.6 0.4 > 103 0.5 0.5 > 301 0.9 0.1 > 303 0.8 0.2 > 304 0.7 0.3 > 403 0.6 0.4 >> voisin <- matrix(c("103","304", "303", "102", "103" ,"303","403","304","303","102","103" ,"303"), > ? ? ? ? ?6,2,dimnames=list(nom.plac2, c("v1","v2")),byrow=T) >> voisin > ? ?v1 ? ?v2 > 102 "103" "304" > 103 "303" "102" > 301 "103" "303" > 303 "403" "304" > 304 "303" "102" > 403 "103" "303" > > So my final result is: > > ? ?102 103 301 303 304 403 > 102 ?NA 0.6 ?NA ?NA 0.4 ?NA > 103 0.5 ?NA ?NA 0.5 ?NA ?NA > 301 ?NA 0.9 ?NA 0.1 ?NA ?NA > 303 ?NA ?NA ?NA ?NA 0.2 0.8 > 304 0.3 ?NA ?NA 0.7 ?NA ?NA > 403 ?NA 0.6 ?NA 0.4 ?NA ?NA > > > So, globally I want to fill for each line of "poids2" data from "wei2" associated with the good the good identifier found in "voisin". > > This can easily be done by a loop: > >> loop <- poids2 >> for(i in 1:6){ > + loop[i,voisin[i,]] <- wei2[i,] > + } > > But I expect it to be quite slow with my larger dataset. > > Does any of you has an idea how I could remove the loop and speed up the operation? > > Best regards, > > > Bastien Ferland-Raymond, M.Sc. Stat., M.Sc. Biol. > Division des orientations et projets sp?ciaux > Direction des inventaires forestiers > Minist?re des Ressources naturelles et de la Faune du Qu?bec > > ______________________________________________ > 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. >-- Jim Holtman Data Munger Guru What is the problem that you are trying to solve? Tell me what you want to do, not how you want to do it.
Try replacing your for loop with the line loop[cbind(as.vector(row(voisin)), match(voisin, nom.plac2))] <- as.vector(wei2) Look help(Subscript) to see how subscripting an n-way array by an n-column integer matrix works. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Bastien.Ferland- > Raymond at mrnf.gouv.qc.ca > Sent: Thursday, November 03, 2011 10:25 AM > To: r-help at r-project.org > Subject: [R] optimising a loop > > Dear R community, > > I'm trying to remove a loop from my code but I'm stock and I can't find a good way to do it. > Hopefully one of you will have something clever to propose. > > Here is a simplified example: > > I have a squared matrix: > > > nom.plac2 <- c("102", "103", "301", "303","304", "403") > > poids2 <- matrix(NA, 6,6, dimnames=list(nom.plac2,nom.plac2)) > > poids2 > 102 103 301 303 304 403 > 102 NA NA NA NA NA NA > 103 NA NA NA NA NA NA > 301 NA NA NA NA NA NA > 303 NA NA NA NA NA NA > 304 NA NA NA NA NA NA > 403 NA NA NA NA NA NA > > I want to replace some of the NAs following specific criterion included in 2 others matrix: > > > wei2 <- matrix(c(.6,.4,.5,.5,.9,.1,.8,.2,.7,.3,.6,.4),6,2,dimnames=list(nom.plac2, > c("p1","p2")),byrow=T) > > wei2 > p1 p2 > 102 0.6 0.4 > 103 0.5 0.5 > 301 0.9 0.1 > 303 0.8 0.2 > 304 0.7 0.3 > 403 0.6 0.4 > > voisin <- matrix(c("103","304", "303", "102", "103" ,"303","403","304","303","102","103" ,"303"), > 6,2,dimnames=list(nom.plac2, c("v1","v2")),byrow=T) > > voisin > v1 v2 > 102 "103" "304" > 103 "303" "102" > 301 "103" "303" > 303 "403" "304" > 304 "303" "102" > 403 "103" "303" > > So my final result is: > > 102 103 301 303 304 403 > 102 NA 0.6 NA NA 0.4 NA > 103 0.5 NA NA 0.5 NA NA > 301 NA 0.9 NA 0.1 NA NA > 303 NA NA NA NA 0.2 0.8 > 304 0.3 NA NA 0.7 NA NA > 403 NA 0.6 NA 0.4 NA NA > > > So, globally I want to fill for each line of "poids2" data from "wei2" associated with the good the > good identifier found in "voisin". > > This can easily be done by a loop: > > > loop <- poids2 > > for(i in 1:6){ > + loop[i,voisin[i,]] <- wei2[i,] > + } > > But I expect it to be quite slow with my larger dataset. > > Does any of you has an idea how I could remove the loop and speed up the operation? > > Best regards, > > > Bastien Ferland-Raymond, M.Sc. Stat., M.Sc. Biol. > Division des orientations et projets sp?ciaux > Direction des inventaires forestiers > Minist?re des Ressources naturelles et de la Faune du Qu?bec > > ______________________________________________ > 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.