Reputation: 39605
Hi everybody I am working with matrix in R and I had a little problem trying to make a division between a 3x3 matrix with a 1x3 matrix. The two matrix I used are alfa
and alfa2
, they have the next structure (I add dput()
version in the last part):
alfa
jul 10 ago 10 sep 10
jul 10 28101696 0 0
ago 10 26558692 2048291 0
sep 10 25234674 2026633 3043638
alfa2
jul 10 ago 10 sep 10
jul 10 1420547 2048291 3043638
I want to make a division between alfa
and alfa2
. Then I use this code alfa/alfa2
and I got this error:
Error in alfa/alfa2 : non-conformable arrays
With this division I want to get a new matrix like this:
jul 10 ago 10 sep 10
jul 10 19.78230 0 0
ago 10 18.69610 1 0
sep 10 17.76405 0.98942 1
Where each column of alfa
is divided by the correspondent column of alfa2
. The dput()
version of alfa
and alfa2
is the next:
alfa
structure(c(28101696.45, 26558692.38, 25234673.68, 0, 2048291.06,
2026632.72, 0, 0, 3043637.6), .Dim = c(3L, 3L), .Dimnames = list(
c("jul 10", "ago 10", "sep 10"), c("jul 10", "ago 10", "sep 10"
)))
alfa2
structure(c(1420547.36, 2048291.06, 3043637.6), .Dim = c(1L,
3L), .Dimnames = list("jul 10", c("jul 10", "ago 10", "sep 10"
)))
Thanks for your help.
Upvotes: 1
Views: 251
Reputation: 132706
t(t(alfa) / drop(alfa2))
# jul 10 ago 10 sep 10
#jul 10 19.78230 0.0000000 0
#ago 10 18.69610 1.0000000 0
#sep 10 17.76405 0.9894261 1
library(microbenchmark)
microbenchmark(
t(t(alfa) / drop(alfa2)),
sweep(alfa, MARGIN = 2, STATS = alfa2, FUN = "/"),
t(apply(alfa,1,"/",alfa2))
)
# Unit: microseconds
# expr min lq median uq max neval
# t(t(alfa)/drop(alfa2)) 17.247 19.4030 20.9430 22.4830 97.934 100
# sweep(alfa, MARGIN = 2, STATS = alfa2, FUN = "/") 42.500 44.9640 45.8880 47.5820 227.282 100
# t(apply(alfa, 1, "/", alfa2)) 76.069 78.9945 80.3805 83.4605 177.390 100
set.seed(42)
alfa <- matrix(rnorm(1000), ncol=10)
alfa2 <- matrix(rnorm(10), ncol=10)
microbenchmark(
t(t(alfa) / drop(alfa2)),
sweep(alfa, MARGIN = 2, STATS = alfa2, FUN = "/"),
t(apply(alfa,1,"/",alfa2))
)
# Unit: microseconds
# expr min lq median uq max neval
# t(t(alfa)/drop(alfa2)) 25.870 27.7180 30.4895 31.722 1191.838 100
# sweep(alfa, MARGIN = 2, STATS = alfa2, FUN = "/") 60.362 64.2125 68.8320 73.913 164.456 100
# t(apply(alfa, 1, "/", alfa2)) 288.259 311.9730 326.4470 383.267 1912.176 100
Upvotes: 0
Reputation: 66844
You can use apply
to divide row-wise, but you need to t
ranspose at the end.
t(apply(alfa,1,"/",alfa2))
[,1] [,2] [,3]
jul 10 19.78230 0.0000000 0
ago 10 18.69610 1.0000000 0
sep 10 17.76405 0.9894261 1
Upvotes: 0
Reputation: 18437
You can use sweep
for this task
sweep(alfa, MARGIN = 2, STATS = alfa2, FUN = "/")
## jul 10 ago 10 sep 10
## jul 10 19.782 0.00000 0
## ago 10 18.696 1.00000 0
## sep 10 17.764 0.98943 1
Upvotes: 4