Search code examples
rlapplysapplydollar-sign

Dollar operator as function argument for sapply not working as expected


I have the following list

test_list=list(list(a=1,b=2),list(a=3,b=4))

and I want to extract all elements with list element name a.

I can do this via

sapply(test_list,`[[`,"a")

which gives me the correct result

#[1] 1 3

When I try the same with Rs dollar operator $, I get NULL

sapply(test_list,`$`,"a")
#[[1]]
#NULL
#
#[[2]]
#NULL

However, if I use it on a single element of test_list it works as expected

`$`(test_list[[1]],"a")
#[1] 1

Am I missing something obvious here?


Solution

  • From what I've been able to determine it's a combination of two things.

    First, the second element of $ is matched but not evaluated so it cannot be a variable.

    Secondly, when arguments are passed to functions they are assigned to the corresponding variables in the function call. When passed to sapply "a" is assigned to a variable and therefore will no longer work with $. We can see this by occurring by running

    sapply("a", print)
    [1] "a"
      a 
    "a"
    

    This can lead to peculiar results like this

    sapply(test_list, function(x, a) {`$`(x, a)})
    [1] 1 3
    

    Where despite a being a variable (which hasn't even been assigned) $ matches it to the names of the elements in the list.