В том же духе, что и ответ @Joris, вот где замечательная функция sweep()
вступает в свои права:
> sweep(x, MARGIN = 2, colMeans(abs(x)), "*")
t0 t1 t2 t3 t4
aa 0.000 0.625 0.00 0.375 0.0
bb 0.625 0.000 0.75 0.000 0.5
cc 0.000 0.000 0.00 0.000 0.0
dd 0.625 0.625 0.75 0.000 0.5
ee 0.625 0.625 0.75 0.000 0.0
ff 0.000 0.000 0.75 0.000 0.5
gg -0.625 -0.625 -0.75 -0.375 0.0
hh -0.625 0.625 -0.75 0.375 -0.5
Что здесь происходит, так это то, что colMeans(abs(x))
- это вектор длины 5. Мы sweep()
эти значения по столбцам (обозначенные MARGIN = 2
в вызове) над данными x
, применяя функцию *
как мы идем. Таким образом, значения в столбце t0
все умножаются на colMeans(abs(x))[1]
, значения в столбце t1
все умножаются на colMeans(abs(x))[2]
и т. Д.
Преимущество sweep()
состоит в том, что он очень быстрый, если задана матрица:
X <- data.matrix(x)
> system.time(replicate(1000, sweep(X, 2, means, "*")))
user system elapsed
0.115 0.000 0.118
> system.time(replicate(1000, mapply(`*`, x, means)))
user system elapsed
0.308 0.001 0.309
> system.time(replicate(1000, mapply(`*`, X, means)))
user system elapsed
0.204 0.000 0.205
Это намного медленнее, если задан кадр данных:
> system.time(replicate(1000, sweep(x, 2, means, "*")))
user system elapsed
2.072 0.000 2.074
Но так обстоит дело в R.