Применить список из n функций для каждой строки кадра данных? - PullRequest
11 голосов
/ 22 января 2011

У меня есть список функций

funs <- list(fn1 = function(x) x^2,
             fn2 = function(x) x^3,               
             fn3 = function(x) sin(x),
             fn4 = function(x) x+1)
#in reality these are all f = splinefun()

И у меня есть датафрейм:

mydata <- data.frame(x1 = c(1, 2, 3, 2),
                     x2 = c(3, 2, 1, 0),
                     x3 = c(1, 2, 2, 3),
                     x4 = c(1, 2, 1, 2))
#actually a 500x15 dataframe of 500 samples from 15 parameters

Для каждой из i строк я бы хотел оценить функцию j для каждого из столбцов j и суммировать результаты:

unlist(funs)
attach(mydata)
a <- rep(NA,4)
for (i in 1:4) {
     a[i] <- sum(fn1(x1[i]), fn2(x2[i]), fn3(x3[i]), fn4(x4[i]))
}

Как я могу сделать это эффективно? Это подходящий случай для реализации plyr функций? Если да, то как?

бонусный вопрос: почему a[4] NA?

Это подходящее время для использования функций из plyr, если да, то как я могу это сделать?

Ответы [ 3 ]

9 голосов
/ 22 января 2011

Игнорируя ваш фрагмент кода и придерживаясь вашей первоначальной спецификации, вы хотите применить функцию j к номеру столбца j и затем "суммировать результаты" ... вы можете сделать :

mapply( do.call, funs, lapply( mydata, list))
#      [,1] [,2]      [,3] [,4]
# [1,]    1   27 0.8414710    2
# [2,]    4    8 0.9092974    3
# [3,]    9    1 0.9092974    3

Я не был уверен, каким образом вы хотите теперь добавить результаты (то есть по строкам или по столбцам), чтобы вы могли сделать rowSums или colSums для этой матрицы. Например:

colSums( mapply( do.call, funs,  lapply( mydata, list)) )
# [1] 14.000000 36.000000  2.660066  8.000000
4 голосов
/ 22 января 2011

Почему бы просто не написать одну функцию для всех 4 и применить ее к фрейму данных? Все ваши функции векторизованы, как и splinefun, и это будет работать:

fun <-  function(df)
    cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1)

rowSums(fun(mydata))

Это значительно эффективнее, чем "подгонка" или "применение" над строками.

0 голосов
/ 22 января 2011

Я пытался использовать plyr::each:

library(plyr)
sapply(mydata, each(min, max))
    x1 x2 x3 x4
min  1  0  1  1
max  3  3  3  2

и работает нормально, но когда я передаю пользовательские функции, я получаю:

sapply(mydata, each(fn1, fn2))
Error in proto[[i]] <- fs[[i]](x, ...) :
  more elements supplied than there are to replace

each имеет очень краткую документацию, я не совсем понимаю, в чем проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...