apply() will also get you there with almost the same arguments in different order (plus t()):> t(apply(a, 1, "/", b))[,1] [,2] [1,] 2 24 [2,] 4 28 [3,] 6 32 [4,] 8 36 [5,] 10 40 ------------------------------------- David L Carlson Department of Anthropology Texas A&M University College Station, TX 77840-4352 -----Original Message----- From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Sarah Goslee Sent: Tuesday, July 28, 2015 8:32 AM To: Steven Yen; r-help Subject: Re: [R] Element-by-element division Hi, It's a good idea to keep discussion on R-help, so others can participate and the results make it into the archives. On Mon, Jul 27, 2015 at 9:11 PM, Steven Yen <syen04 at gmail.com> wrote:> Thanks Sarah. That serves my need. I however find ?sweep hard to comprehend.Heh. The help makes it seem more complicated than it really is. It isn't that hard: sweep(a, 2, b, "/") a: the object to act on 2: the direction to go (1 for rows, 2 for columns - a has 2 columns and b is of length 2, so you need to choose columns) b: the vector to use (?sweep calls this "the summary statistic" because the use case was originally conceived of as being: "divide columns by standard deviation" and such) "/": the function to use so to add vector x to the rows of a, you'd do: sweep(a, 1, x, "+") The default FUN is "-", so the first example in the help subtracts the median from the columns: require(stats) # for median med.att <- apply(attitude, 2, median) sweep(data.matrix(attitude), 2, med.att) # subtract the column medians The complicated bits come in if b is an array instead of a vector, or if the dimensions aren't identical. For your case, and for most cases, none of that matters. Sarah> What am I missing? The S language? > Steven Yen > > On 7/27/2015 4:17 PM, Sarah Goslee wrote: > > Hi, > > See ?sweep > > For instance, to get your matrix two: > > sweep(a, 2, b, "/") > > [,1] [,2] > [1,] 2 24 > [2,] 4 28 > [3,] 6 32 > [4,] 8 36 > [5,] 10 40 > > > Sarah > > On Mon, Jul 27, 2015 at 4:04 PM, Steven Yen <syen04 at gmail.com> wrote: > > I need help with element-by-element division. Below, matrices a and c are > both 5 x 2 and element-by-element division works as (I) expected. What if > matrix is 1 by 2: to divide first column of a by b[1] and second column of > a by b[2]. I had to go around (two ways) to make it work. In Gauss, these > can be dine by a./b and a./c. Any such simple way in R? Thank! > > a<-matrix(1:10,nrow=5); a > > [,1] [,2] > [1,] 1 6 > [2,] 2 7 > [3,] 3 8 > [4,] 4 9 > [5,] 5 10 > > b<-matrix(c(0.5,0.25),nrow=1); b > > [,1] [,2] > [1,] 0.5 0.25 > > c<-matrix(rep(c(0.5,0.25),5),nrow=5,byrow=T); c > > [,1] [,2] > [1,] 0.5 0.25 > [2,] 0.5 0.25 > [3,] 0.5 0.25 > [4,] 0.5 0.25 > [5,] 0.5 0.25 > > one<-a/c; one [,1] [,2] > > [1,] 2 24 > [2,] 4 28 > [3,] 6 32 > [4,] 8 36 > [5,] 10 40 > > > two<-a/b > > Error in a/b : non-conformable arrays > > two<-cbind(a[,1]/b[1],a[,2]/b[2]); two > > [,1] [,2] > [1,] 2 24 > [2,] 4 28 > [3,] 6 32 > [4,] 8 36 > [5,] 10 40 > > b2<-matrix(rep(b,5),nrow=5,byrow=T); b2 [,1] [,2] > > [1,] 0.5 0.25 > [2,] 0.5 0.25 > [3,] 0.5 0.25 > [4,] 0.5 0.25 > [5,] 0.5 0.25> a/b2 [,1] [,2] > [1,] 2 24 > [2,] 4 28 > [3,] 6 32 > [4,] 8 36 > [5,] 10 40 > >______________________________________________ R-help at 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.
On Tue, Jul 28, 2015 at 9:42 AM, David L Carlson <dcarlson at tamu.edu> wrote:> apply() will also get you there with almost the same arguments in different order (plus t()):Sure, there are lots of ways to do everything in R. But mixing in apply muddles the issue, since apply() and sweep() use different logic to determine MARGIN. It probably doesn't matter much, but sweep is also a lot more efficient (possibly because of that pesky t()):> a <- matrix(runif(500), ncol=10) > b <- runif(10) > > system.time(+ for(i in 1:50000) { + aout <- sweep(a, 2, b, "/") + }) user system elapsed 2.628 0.000 2.628> > > system.time(+ for(i in 1:50000) { + aout <- t(apply(a, 1, "/", b)) + }) user system elapsed 8.294 0.025 8.320> >> t(apply(a, 1, "/", b)) > [,1] [,2] > [1,] 2 24 > [2,] 4 28 > [3,] 6 32 > [4,] 8 36 > [5,] 10 40 > > ------------------------------------- > David L Carlson > Department of Anthropology > Texas A&M University > College Station, TX 77840-4352 > > -----Original Message----- > From: R-help [mailto:r-help-bounces at r-project.org] On Behalf Of Sarah Goslee > Sent: Tuesday, July 28, 2015 8:32 AM > To: Steven Yen; r-help > Subject: Re: [R] Element-by-element division > > Hi, > > It's a good idea to keep discussion on R-help, so others can > participate and the results make it into the archives. > > On Mon, Jul 27, 2015 at 9:11 PM, Steven Yen <syen04 at gmail.com> wrote: >> Thanks Sarah. That serves my need. I however find ?sweep hard to comprehend. > > Heh. The help makes it seem more complicated than it really is. It > isn't that hard: > > sweep(a, 2, b, "/") > > a: the object to act on > 2: the direction to go (1 for rows, 2 for columns - a has 2 columns > and b is of length 2, so you need to choose columns) > b: the vector to use (?sweep calls this "the summary statistic" > because the use case was originally conceived of as being: "divide > columns by standard deviation" and such) > "/": the function to use > > so to add vector x to the rows of a, you'd do: > sweep(a, 1, x, "+") > > The default FUN is "-", so the first example in the help subtracts the > median from the columns: > require(stats) # for median > med.att <- apply(attitude, 2, median) > sweep(data.matrix(attitude), 2, med.att) # subtract the column medians > > The complicated bits come in if b is an array instead of a vector, or > if the dimensions aren't identical. For your case, and for most cases, > none of that matters. > > Sarah > >> What am I missing? The S language? >> Steven Yen >> >> On 7/27/2015 4:17 PM, Sarah Goslee wrote: >> >> Hi, >> >> See ?sweep >> >> For instance, to get your matrix two: >> >> sweep(a, 2, b, "/") >> >> [,1] [,2] >> [1,] 2 24 >> [2,] 4 28 >> [3,] 6 32 >> [4,] 8 36 >> [5,] 10 40 >> >> >> Sarah >> >> On Mon, Jul 27, 2015 at 4:04 PM, Steven Yen <syen04 at gmail.com> wrote: >> >> I need help with element-by-element division. Below, matrices a and c are >> both 5 x 2 and element-by-element division works as (I) expected. What if >> matrix is 1 by 2: to divide first column of a by b[1] and second column of >> a by b[2]. I had to go around (two ways) to make it work. In Gauss, these >> can be dine by a./b and a./c. Any such simple way in R? Thank! >> >> a<-matrix(1:10,nrow=5); a >> >> [,1] [,2] >> [1,] 1 6 >> [2,] 2 7 >> [3,] 3 8 >> [4,] 4 9 >> [5,] 5 10 >> >> b<-matrix(c(0.5,0.25),nrow=1); b >> >> [,1] [,2] >> [1,] 0.5 0.25 >> >> c<-matrix(rep(c(0.5,0.25),5),nrow=5,byrow=T); c >> >> [,1] [,2] >> [1,] 0.5 0.25 >> [2,] 0.5 0.25 >> [3,] 0.5 0.25 >> [4,] 0.5 0.25 >> [5,] 0.5 0.25 >> >> one<-a/c; one [,1] [,2] >> >> [1,] 2 24 >> [2,] 4 28 >> [3,] 6 32 >> [4,] 8 36 >> [5,] 10 40 >> >> >> two<-a/b >> >> Error in a/b : non-conformable arrays >> >> two<-cbind(a[,1]/b[1],a[,2]/b[2]); two >> >> [,1] [,2] >> [1,] 2 24 >> [2,] 4 28 >> [3,] 6 32 >> [4,] 8 36 >> [5,] 10 40 >> >> b2<-matrix(rep(b,5),nrow=5,byrow=T); b2 [,1] [,2] >> >> [1,] 0.5 0.25 >> [2,] 0.5 0.25 >> [3,] 0.5 0.25 >> [4,] 0.5 0.25 >> [5,] 0.5 0.25> a/b2 [,1] [,2] >> [1,] 2 24 >> [2,] 4 28 >> [3,] 6 32 >> [4,] 8 36 >> [5,] 10 40 >>
> On 28 Jul 2015, at 15:53 , Sarah Goslee <sarah.goslee at gmail.com> wrote: > > Sure, there are lots of ways to do everything in R. But mixing in > apply muddles the issue, since apply() and sweep() use different logic > to determine MARGIN.Actually, apply() and sweep() were designed together and use exactly the SAME logic to determine the margin. E.g., to sweep out means according to the last two dimensions of an array, you do> m <- array(1:24, c(4,3,2)) > (mm <- apply(m, c(2,3), mean))[,1] [,2] [1,] 2.5 14.5 [2,] 6.5 18.5 [3,] 10.5 22.5> sweep(m, c(2,3), mm, "-"), , 1 [,1] [,2] [,3] [1,] -1.5 -1.5 -1.5 [2,] -0.5 -0.5 -0.5 [3,] 0.5 0.5 0.5 [4,] 1.5 1.5 1.5 , , 2 [,1] [,2] [,3] [1,] -1.5 -1.5 -1.5 [2,] -0.5 -0.5 -0.5 [3,] 0.5 0.5 0.5 [4,] 1.5 1.5 1.5 The trouble comes when people miss the point and start using apply() in ways it wasn't designed for... -pd -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com