Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lapply with "$" function

Tags:

r

lapply

Let's say I have a list of data.frames

dflist <- list(data.frame(a=1:3), data.frame(b=10:12, a=4:6)) 

If i want to extract the first column from each item in the list, I can do

lapply(dflist, `[[`, 1) # [[1]] # [1] 1 2 3 #  # [[2]] # [1] 10 11 12 

Why can't I use the "$" function in the same way

lapply(dflist, `$`, "a") # [[1]] # NULL #  # [[2]] # NULL 

But these both work:

lapply(dflist, function(x) x$a) `$`(dflist[[1]], "a") 

I realize that in this case one could use

lapply(dflist, `[[`, "a") 

but I was working with an S4 object that didn't seem to allow indexing via [[. For example

library(adegenet) data(nancycats) catpop <- genind2genpop(nancycats) mylist <- list(catpop, catpop)  #works catpop[[1]]$tab  #doesn't work lapply(mylist, "$", "tab") # Error in slot(x, name) :  #   no slot of name "..." for this object of class "genpop"  #doesn't work lapply(mylist, "[[", "tab") # Error in FUN(X[[1L]], ...) : this S4 class is not subsettable 
like image 973
MrFlick Avatar asked May 08 '15 19:05

MrFlick


People also ask

What is Lapply function?

The lapply() function helps us in applying functions on list objects and returns a list object of the same length. The lapply() function in the R Language takes a list, vector, or data frame as input and gives output in the form of a list object.

Which function is very similar to Lapply?

sapply() function It is useful for operations on list objects and returns a list object of same length of original set. Sapply function in R does the same job as lapply() function but returns a vector.

What is the difference between Lapply () and Sapply () functions?

Difference between lapply() and sapply() functions:lapply() function displays the output as a list whereas sapply() function displays the output as a vector. lapply() and sapply() functions are used to perform some operations in a list of objects.


1 Answers

For the first example, you can just do:

lapply(dflist, `$.data.frame`, "a") 

For the second, use the slot() accessor function

lapply(mylist, "slot", "tab") 

I'm not sure why method dispatch doesn't work in the first case, but the Note section of ?lapply does address this very issue of its borked method dispatch for primitive functions like $:

 Note:   [...]   For historical reasons, the calls created by ‘lapply’ are  unevaluated, and code has been written (e.g., ‘bquote’) that  relies on this.  This means that the recorded call is always of  the form ‘FUN(X[[i]], ...)’, with ‘i’ replaced by the current  (integer or double) index.  This is not normally a problem, but it  can be if ‘FUN’ uses ‘sys.call’ or ‘match.call’ or if it is a  primitive function that makes use of the call.  This means that it  is often safer to call primitive functions with a wrapper, so that  e.g. ‘lapply(ll, function(x) is.numeric(x))’ is required to ensure  that method dispatch for ‘is.numeric’ occurs correctly. 
like image 168
Josh O'Brien Avatar answered Sep 23 '22 00:09

Josh O'Brien