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 col
So it seems that this problem has more to do with $
and how it typically expects unquoted names as the second parameter rather than strings. Look at this example
dflist <- list(
data.frame(a=1:3, z=31:33),
data.frame(b=10:12, a=4:6, z=31:33)
)
lapply(dflist,
function(x, z) {
print(paste("z:",z));
`$`(x,z)
},
z="a"
)
We see the results
[1] "z: a"
[1] "z: a"
[[1]]
[1] 31 32 33
[[2]]
[1] 31 32 33
so the z
value is being set to "a", but $
isn't evaluating the second parameter. So it's returning the "z" column rather than the "a" column. This leads to this interesting set of results
a<-"z"; `$`(dflist[[1]], a)
# [1] 1 2 3
a<-"z"; `$`(dflist[[1]], "z")
# [1] 31 32 33
a<-"z"; `$.data.frame`(dflist[[1]], a)
# [1] 31 32 33
a<-"z"; `$.data.frame`(dflist[[1]], "z")
# [1] 31 32 33
When we call $.data.frame
directly we are bypassing the standard deparsing that occurs in the primitive prior to dispatching (which happens near here in the source).
The added catch with lapply
is that it passes along arguments to the function via the ...
mechanism. For example
lapply(dflist, function(x, z) sys.call())
# [[1]]
# FUN(X[[2L]], ...)
# [[2]]
# FUN(X[[2L]], ...)
This means that when $
is invoked, it deparses the ...
to the string "..."
. This explains this behavior
dflist<- list(data.frame(a=1:3, "..."=11:13, check.names=F))
lapply(dflist, `$`, "a")
# [[1]]
# [1] 11 12 13
Same thing happens when you try to use ...
yourself
f<-function(x,...) `$`(x, ...);
f(dflist[[1]], "a");
# [1] 11 12 13
`$`(dflist[[1]], "a")
# [1] 1 2 3