Применить список функций к матрице и вернуть матрицу в результате в R - PullRequest
0 голосов
/ 26 июня 2018

У меня есть матрица из n столбцов и m строк и список функций f .Каждая функция занимает одну строку матрицы и возвращает одно значение: p .

Каков наилучший способ создания столбцов f по m матрица строк?

В настоящее время я делаю это:

# 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))

Редактирование разъяснений: приведенный выше код работает, но мне интересно, есть ли более элегантный подход.

Ответы [ 3 ]

0 голосов
/ 26 июня 2018
С данными:
set.seed(11235813)

m <- matrix(rexp(25, rate=.1), ncol=5)

fs <- c("mean", "median", "sd", "max", "min", "sum")
Вы можете сделать:
sapply(fs, mapply, split(m, row(m)), USE.NAMES = T)
Что возвращает:
          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

Примечание:

Это самый медленный один, по сравнению с обоими подходами, предложенными выше.

0 голосов
/ 27 июня 2018

Вот как я приспособил @ patL's answer для получения списка функций:

# 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))

Я использую это для оценки множества моделей, например:

# 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))
0 голосов
/ 26 июня 2018

С помощью 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

это быстрее, чем подход do.call:

microbenchmark::microbenchmark(
  do.call("cbind", lapply(fs, g)),
  cbind(apply(m, 1, mean), apply(m, 1, min))
)

, что приводит к:

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...