[R] Element-by-element division

Sarah Goslee sarah.goslee at gmail.com
Tue Jul 28 15:53:05 CEST 2015


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
>>



More information about the R-help mailing list