Reputation: 37
attach(airquality)
s <- split(airquality, airquality$Month)
If I run
lapply(s, colMeans(s[,c("Ozone","Solar.R","Wind")]))
An error comes. It says incorrect number of dimensions.
lapply(airquality, function(x)colMeans(x))
Also shows same error.
lapply(s, function(x)colMeans(s[,"Ozone","Solar.R","Wind"])
This code works perfectly fine.
But:
f<-function(x){
colMeans(x[,c("Ozone","Solar.R","Wind")])}
f(s) #error incorrect dimensions
class(s) # class of s is list
f(airquality) #gives mean of each column
Is function()
creating dimensions? If it is then why lapply
on airquality
isn't working?
Upvotes: 1
Views: 634
Reputation: 7590
Your split function returns a list, but you are manipulating it like an array or data frame.
The error is coming from s[,c("Ozone","Solar.R","Wind")]
, which can't be subsetted this way as it is a list. Try
s$`9`[,c("Ozone","Solar.R","Wind")]
and you will see that this works, as
s$`9`
is a dataframe.
In your first attempt, you are not suppling a function, but a function evaluated on s. As you can't manipulate s like above, calling a function on it also causes the same error, as the input to the function is problematic to begin with.
Your second attempt fails, because lapply is going to end up feeding each column one by one to the colMeans function, which expects two dimensional arrays (and you have given it one dimensional arrays)
The reason that the last call works is that the function
function(x)colMeans(x[,c("Ozone","Solar.R","Wind")])
can be called on each item of the list s as each item is a dataframe. The lapply function simply applies this to each item in that list.
lapply(s,function(x)colMeans(x[,c("Ozone","Solar.R","Wind")]))
is the correct way to approach this.
An alternative way would be with the by function
by(airquality[,c("Ozone","Solar.R","Wind")],airquality$Month,colMeans)
Upvotes: 4