apply a function across columns in R

Viewed 304

Let's say I have a dataframe (df) in R:

df <- data.frame(x = rnorm(5, mean = 5), u = rnorm(5, mean = 5), y = rnorm(5, mean = 5), z = rnorm(5, mean = 5))

print(df)

I want to get the mean absolute difference (MAD) between the first column (x) and the other columns.

With this function, I can find the MAD between the first column and another (the second for example):

mad <- function(dat){
      abs(mean(dat[,1] - dat[,2], na.rm = TRUE))
}
mad(dat = df)

But I want to generalize the function to apply across all of the columns. Changing the function to something like this:

mad <- function(dat) {
     abs(mean(dat[,1] - dat[,2:4], na.rm = TRUE))
}
mad(dat = df)

does not work and returns this error: "argument is not numeric or logical: returning NA"

I was thinking of using apply() across the dataframe, as that seems to be the general advice that I've found on here. But I don't understand how to keep the first column constant and subtract the other columns from the first.

2 Answers

We can create the function with two arguments

mad <- function(x, y) abs(mean(x - y, na.rm = TRUE))

and use sapply/lapply to loop over the columns other than 1, apply the mad function by extracting the first column of data with the looped column values

sapply(df[-1], function(x) mad(df[,1], x))
#         u           y           z 
#0.003399429 0.991685267 0.710553411 

Here is another option without defining mad function:

sapply(abs(df[-1] - df[["x"]]), mean, na.rm = TRUE)
Related