Применить список n функций к каждой строке данных?
У меня есть список функций
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()
И у меня есть dataframe:
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
Для каждой из я строк я хотел бы оценить функцию 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
, если да, то как я могу это сделать?
Ответы
Ответ 1
Игнорируя фрагмент кода и придерживаясь первоначальной спецификации, которую вы хотите применить функцию 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
Ответ 2
Почему бы просто не написать одну функцию для всех 4 и применить ее к кадру данных?
Все ваши функции векторизованы, и поэтому splinefun
, и это будет работать:
fun <- function(df)
cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1)
rowSums(fun(mydata))
Это значительно эффективнее, чем "форсирование" или "применение" по строкам.
Ответ 3
Я попытался использовать 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
имеет очень краткую документацию, я не совсем понимаю, в чем проблема.