如何将矩阵的每一行除以 R 中向量的元素 [英] How to divide each row of a matrix by elements of a vector in R
问题描述
我想将矩阵的每一行除以一个固定向量.例如
I would like to divide each row of a matrix by a fixed vector. For example
mat<-matrix(1,ncol=2,nrow=2,TRUE)
dev<-c(5,10)
Giving mat/dev
将每个列除以 dev
.
Giving mat/dev
divides each column by dev
.
[,1] [,2]
[1,] 0.2 0.2
[2,] 0.1 0.1
但是,我希望得到这样的结果,即按行进行操作:
However, I would like to have this as a result, i.e. do the operation row-wise :
rbind(mat[1,]/dev, mat[2,]/dev)
[,1] [,2]
[1,] 0.2 0.1
[2,] 0.2 0.1
是否有明确的命令可以到达那里?
Is there an explicit command to get there?
推荐答案
以下是几种增加代码长度的方法:
Here are a few ways in order of increasing code length:
t(t(mat) / dev)
mat / dev[col(mat)] # @DavidArenburg & @akrun
mat %*% diag(1 / dev)
sweep(mat, 2, dev, "/")
t(apply(mat, 1, "/", dev))
plyr::aaply(mat, 1, "/", dev)
mat / rep(dev, each = nrow(mat))
mat / t(replace(t(mat), TRUE, dev))
mapply("/", as.data.frame(mat), dev) # added later
mat / matrix(dev, nrow(mat), ncol(mat), byrow = TRUE) # added later
do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev))
mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev
数据帧
所有以 mat/
开头的解决方案也适用于如果 mat
是一个数据框并产生一个数据框结果.sweep
解决方案和最后一个,即 mat2
解决方案的情况也是如此.mapply
解决方案适用于 data.frames,但会生成一个矩阵.
Data Frames
All the solutions that begin with mat /
also work if mat
is a data frame and produce a data frame result. The same is also the case for the sweep
solution and the last, i.e. mat2
, solution. The mapply
solutions works with data.frames but produces a matrix.
如果 mat
是一个普通向量而不是一个矩阵,那么它们中的任何一个都返回一个单列矩阵
If mat
is a plain vector rather than a matrix then either of these return a one column matrix
t(t(mat) / dev)
mat / t(replace(t(mat), TRUE, dev))
这个返回一个向量:
plyr::aaply(mat, 1, "/", dev)
其他人给出错误、警告或不是想要的答案.
The others give an error, warning or not the desired answer.
代码的简洁性和清晰度可能比速度更重要,但为了完整起见,这里有一些基准测试,分别使用 10 次重复和 100 次重复.
The brevity and clarity of the code may be more important than speed but for purposes of completeness here are some benchmarks using 10 repetitions and then 100 repetitions.
library(microbenchmark)
library(plyr)
set.seed(84789)
mat<-matrix(runif(1e6),nrow=1e5)
dev<-runif(10)
microbenchmark(times=10L,
"1" = t(t(mat) / dev),
"2" = mat %*% diag(1/dev),
"3" = sweep(mat, 2, dev, "/"),
"4" = t(apply(mat, 1, "/", dev)),
"5" = mat / rep(dev, each = nrow(mat)),
"6" = mat / t(replace(t(mat), TRUE, dev)),
"7" = aaply(mat, 1, "/", dev),
"8" = do.call(rbind, lapply(as.data.frame(t(mat)), "/", dev)),
"9" = {mat2 <- mat; for(i in seq_len(nrow(mat2))) mat2[i, ] <- mat2[i, ] / dev},
"10" = mat/dev[col(mat)])
给予:
Unit: milliseconds
expr min lq mean median uq max neval
1 7.957253 8.136799 44.13317 8.370418 8.597972 366.24246 10
2 4.678240 4.693771 10.11320 4.708153 4.720309 58.79537 10
3 15.594488 15.691104 16.38740 15.843637 16.559956 19.98246 10
4 96.616547 104.743737 124.94650 117.272493 134.852009 177.96882 10
5 17.631848 17.654821 18.98646 18.295586 20.120382 21.30338 10
6 19.097557 19.365944 27.78814 20.126037 43.322090 48.76881 10
7 8279.428898 8496.131747 8631.02530 8644.798642 8741.748155 9194.66980 10
8 509.528218 524.251103 570.81573 545.627522 568.929481 821.17562 10
9 161.240680 177.282664 188.30452 186.235811 193.250346 242.45495 10
10 7.713448 7.815545 11.86550 7.965811 8.807754 45.87518 10
对所有耗时 <20 毫秒并重复 100 次的测试重新运行:
Re-running the test on all those that took <20 milliseconds with 100 repetitions:
microbenchmark(times=100L,
"1" = t(t(mat) / dev),
"2" = mat %*% diag(1/dev),
"3" = sweep(mat, 2, dev, "/"),
"5" = mat / rep(dev, each = nrow(mat)),
"6" = mat / t(replace(t(mat), TRUE, dev)),
"10" = mat/dev[col(mat)])
给予:
Unit: milliseconds
expr min lq mean median uq max neval
1 8.010749 8.188459 13.972445 8.560578 10.197650 299.80328 100
2 4.672902 4.734321 5.802965 4.769501 4.985402 20.89999 100
3 15.224121 15.428518 18.707554 15.836116 17.064866 42.54882 100
5 17.625347 17.678850 21.464804 17.847698 18.209404 303.27342 100
6 19.158946 19.361413 22.907115 19.772479 21.142961 38.77585 100
10 7.754911 7.939305 9.971388 8.010871 8.324860 25.65829 100
所以在这两个测试中,#2(使用 diag
)是最快的.原因可能在于它几乎直接对 BLAS 有吸引力,而 #1 依赖于更昂贵的 t
.
So on both these tests #2 (using diag
) is fastest. The reason may lie in its almost direct appeal to the BLAS, whereas #1 relies on the costlier t
.
这篇关于如何将矩阵的每一行除以 R 中向量的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!