[英]Apply a list of functions to matrix and return a matrix as a result in R
I have a matrix of n columns and m rows and a list of f functions. 我有一个n列和m行的矩阵和一个f函数列表。 Each function takes one row of the matrix and returns a single value, p . 每个函数占用矩阵的一行并返回单个值p 。
What is the best way to generate a f columns by m rows matrix? 用m行矩阵生成f列的最佳方法是什么?
At present I am doing this: 目前我这样做:
# create a random 5x5 matrix
m <- matrix(rexp(25, rate=.1), ncol=5)
# example functions, in reality more complex but with the same signature
fs <- list(function(xs) { return(mean(xs)) }, function(xs) { return(min(xs)) } )
# create a function which takes a function and applies it to each row of m
g <- function(f) { return(apply(m, 1, f)) }
# use lapply to make a call for each function in fs
# use do.call and cbind to reshape the output from a list of lists to a matrix
do.call("cbind", lapply(fs, g))
Clarification edit: the above code does work, but I'm wondering if there is a more elegant approach. 澄清编辑:上面的代码确实有效,但我想知道是否有更优雅的方法。
With base
R you can do it in one line: 使用base
R,您可以在一行中完成:
cbind(apply(m, 1, mean), apply(m, 1, min))
# [,1] [,2]
#[1,] 13.287748 5.2172657
#[2,] 5.855862 1.8346868
#[3,] 8.077236 0.4162899
#[4,] 10.422803 1.5899831
#[5,] 10.283001 2.0444687
this is faster than the do.call
approach: 这比do.call
方法更快:
microbenchmark::microbenchmark(
do.call("cbind", lapply(fs, g)),
cbind(apply(m, 1, mean), apply(m, 1, min))
)
which yelds: 哪个yelds:
#Unit: microseconds
# expr min lq mean
# do.call("cbind", lapply(fs, g)) 66.077 67.210 88.75483
# cbind(apply(m, 1, mean), apply(m, 1, min)) 57.771 58.903 67.70094
# median uq max neval
# 67.965 71.741 851.446 100
# 59.658 60.036 125.735 100
This is how I've adapted @patL's answer to take a list of functions: 这就是我如何改编@ patL的答案来获取一系列功能:
# create a random 5x5 matrix
m <- matrix(rexp(25, rate=.1), ncol=5)
# example functions, in reality more complex but with the same signature
fs <- list(function(xs) { return(mean(xs)) }, function(xs) { return(min(xs)) } )
# create a function which takes a function and applies it to each row of m
g <- function(f) { return(apply(m, 1, f)) }
# use sapply to make a call for each function in fs
# use cbind to reshape the output from a list of lists to a matrix
cbind(sapply(fs, g))
I am using this to score an ensemble of models, for example: 我用这个来评分一组模型,例如:
# models is a list of trained models and m is a matrix of input data
g <- function(model) { return(predict(model, m)) }
# produce a matrix of model scores
cbind(sapply(models, g))
mean median sd max min sum
[1,] 9.299471 3.531394 10.436391 26.37984 1.7293010 46.49735
[2,] 8.583419 2.904223 11.714482 28.75344 0.7925614 42.91709
[3,] 6.292835 4.578894 6.058633 16.92280 1.8387221 31.46418
[4,] 10.699276 5.688477 15.161685 36.91369 0.1049507 53.49638
[5,] 9.767307 2.748114 10.767438 24.66143 1.5677153 48.83653
You can do:
你可以做:
sapply(fs, mapply, split(m, row(m)), USE.NAMES = T)
Which returns:
哪个回报:
mean median sd max min sum [1,] 9.299471 3.531394 10.436391 26.37984 1.7293010 46.49735 [2,] 8.583419 2.904223 11.714482 28.75344 0.7925614 42.91709 [3,] 6.292835 4.578894 6.058633 16.92280 1.8387221 31.46418 [4,] 10.699276 5.688477 15.161685 36.91369 0.1049507 53.49638 [5,] 9.767307 2.748114 10.767438 24.66143 1.5677153 48.83653
Note: 注意:
It is the slowest one, comparing to both approaches proposed above. 与上面提出的两种方法相比,它是最慢的 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.