Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply a list of n functions to each row of a dataframe?

Tags:

r

apply

plyr

I have a list of functions

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

And I have a 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

For each of i rows, I would like to evaluate function j on each of the j columns and sum the results:

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]))
}

How can I do this efficiently? Is this an appropriate occasion to implement plyr functions? If so, how?

bonus question: why is a[4] NA?

Is this an appropriate time to use functions from plyr, if so, how can I do so?

like image 890
Abe Avatar asked Jan 21 '11 23:01

Abe


People also ask

How do I apply a function to each row of a DataFrame?

Use apply() function when you wanted to update every row in pandas DataFrame by calling a custom function. In order to apply a function to every row, you should use axis=1 param to apply(). By applying a function to each row, we can create a new column by using the values from the row, updating the row e.t.c.

How do you apply a function to each element of a DataFrame?

If you want to apply a function element-wise, you can use applymap() function. This function doesn't have additional arguments. The function is applied to each of the element and the returned value is used to create the result DataFrame object.

What is data ISNA () SUM ()?

isna(). sum() returns the number of missing values in each column.


1 Answers

Ignoring your code snippet and sticking to your initial specification that you want to apply function j on the column number j and then "sum the results"... you can do:

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

I wasn't sure which way you want to now add the results (i.e. row-wise or column-wise), so you could either do rowSums or colSums on this matrix. E.g:

colSums( mapply( do.call, funs,  lapply( mydata, list)) )
# [1] 14.000000 36.000000  2.660066  8.000000
like image 68
Prasad Chalasani Avatar answered Nov 15 '22 20:11

Prasad Chalasani