D L Dahly
D L Dahly

Reputation: 560

R: sapply works but lapply doesn't

I am trying to better understand the difference between lapply and sapply. In the example below, why does the later work, but not the former?

# Data

  data <- data.frame("A" = rnorm(500, 0, 1), 
                     "B" = rnorm(500, 0, 1), 
                     "C" = sample(c("a", "b" , "c"), 500, replace = T))

# Give the mean of all numeric elements in the dataframe. 

  lapply(data[lapply(data, is.numeric)], mean) # Doesn't work

  Error in `[.default`(data, lapply(data, is.numeric)) : 
  invalid subscript type 'list'

  lapply(data[sapply(data, is.numeric)], mean) # Works

Upvotes: 3

Views: 1151

Answers (3)

devm2024
devm2024

Reputation: 11

Better use

data %>% summarize_if(is.numeric, mean)

Upvotes: 0

LyzandeR
LyzandeR

Reputation: 37879

lapply returns a list by default:

From documentation:

lapply returns a list of the same length as X, each element of which is the result of applying FUN to the corresponding element of X.

sapply returns a vector by default:

From documentation:

sapply is a user-friendly version and wrapper of lapply by default returning a vector.

So, when you slice/subset a data.frame like this data[sapply(data, is.numeric)] you need to pass a vector of elements otherwise it wont work. And that's why sapply works and lapply doesn't.

Upvotes: 4

cdeterman
cdeterman

Reputation: 19960

It isn't working because you are trying to subset with a list, hence the error message you omitted. If you have your heart set on using the double lapply you can unlist the inner part.

lapply(data[unlist(lapply(data, is.numeric))], mean)

Upvotes: 4

Related Questions