我有这个R代码:
> coef
[1] 1.5 2.4 3.9 4.4
> y
[,1] [,2] [,3] [,4]
[1,] 1 2 12 45
[2,] 5 6 7 8
[3,] 9 10 2 12
[4,] 13 14 15 45
[5,] 17 18 39 7
我必须将列的每个值乘以相应的coef。结果应该是:
First column:
1*1.5
5*1.5
9*1.5
13*1.5
17*1.5
Second column:
2*2.4
6*2.4
10*2.4
14*2.4
18*2.4
Third column:
12*3.9
7*3.9
2*3.9
15*3.9
39*3.9
Fourth column:
45*4.4
8*4.4
12*4.4
45*4.4
7*4.4
所有列的值都在向量中的相同索引处乘以相同的系数。
我该怎么做这个计算?
解决方案可能是:
> y[,1] <- y[,1] * coef[1]
> y[,2] <- y[,2] * coef[2]
> y[,3] <- y[,3] * coef[3]
> y[,4] <- y[,4] * coef[4]
但似乎没有太优化!还有更好的东西吗?
谢谢!
答案 0 :(得分:7)
这会给你你想要的东西:
t( t(y) * coef )
答案 1 :(得分:6)
还有两种可能性:sweep
和scale
(后者只按列操作,在我看来有点像黑客)。
coef <- c(1.5,2.4,3.9,4.4)
y <- matrix(c(seq(1,17,by=4),
seq(2,18,by=4),
c(12,7,2,15,39,
45,8,12,45,7)),
ncol=4)
t(t(y)*coef)
t(apply(y,1,"*",coef))
sweep(y,2,coef,"*")
scale(y,center=FALSE,scale=1/coef)
library(rbenchmark)
benchmark(t(t(y)*coef),
y %*% diag(coef),
t(apply(y,1,"*",coef)),
sweep(y,2,coef,"*"),
scale(y,center=FALSE,scale=1/coef),
replications=1e4)
test replications elapsed relative
5 scale(y, center = FALSE, scale = 1/coef) 10000 0.990 4.342105
4 sweep(y, 2, coef, "*") 10000 0.846 3.710526
3 t(apply(y, 1, "*", coef)) 10000 1.537 6.741228
1 t(t(y) * coef) 10000 0.228 1.000000
2 y %*% diag(coef) 10000 0.365 1.600877
编辑:从@baptiste添加y %*% diag(coef)
[不是最快的,虽然对于充分优化的BLAS包的大问题可能会如此...] [并且它最快另一个试验,所以我可能没有一个稳定的估计]
修改:修复t(t(y)*coef)
中的拼写错误[感谢Timur Shtatland](但不更新时间,因此它们可能稍微偏离......)
我也试过library(Matrix); y %*% Diagonal(x=coef)
,这个例子的非常慢,但对于一个大矩阵(??)可能很快。 (我也尝试过只构造一次对角矩阵,但是在这个例子中,即使乘以预定矩阵也很慢(比最好的慢25倍,而在动态定义矩阵时慢47倍)。
我对sweep
有一个温和的偏好,因为我认为它最清楚地表达了正在进行的操作(“将列乘以coef
的元素”)
答案 2 :(得分:5)
apply(y, 1, "*", coef)
# -- result --
[,1] [,2] [,3] [,4] [,5]
[1,] 1.5 7.5 13.5 19.5 25.5
[2,] 4.8 14.4 24.0 33.6 43.2
[3,] 46.8 27.3 7.8 58.5 152.1
[4,] 198.0 35.2 52.8 198.0 30.8
答案 3 :(得分:3)
迟到:
coef[col(y)]*y
在我的系统上,这是最快的。
test replications elapsed relative
6 coef[col(y)] * y 10000 0.068 1.000
5 scale(y, center = FALSE, scale = 1/coef) 10000 0.640 9.412
4 sweep(y, 2, coef, "*") 10000 0.535 7.868
3 t(apply(y, 1, "*", coef)) 10000 0.837 12.309
1 t(t(y) * coef) 10000 0.176 2.588
2 y %*% diag(coef) 10000 0.187 2.750