Reputation: 21492
A followup to this How to use `[[` and `$` as a function? question: I started playing a bit with the original setup (reduced the size from 10000 to 3 for simplicity)
JSON <- rep(list(x,y),3)
x <- list(a=1, b=1)
y <- list(a=1)
JSON <- rep(list(x,y),3)
sapply(JSON, "[[", "a")
[1] 1 1 1 1 1 1
sapply(JSON,"[[",'b')
[[1]]
[1] 1
[[2]]
NULL
[[3]]
[1] 1
[[4]]
NULL
[[5]]
[1] 1
[[6]]
NULL
sapply(JSON,'[[',1)
[1] 1 1 1 1 1 1
sapply(JSON,'[[',2)
Error in FUN(X[[2L]], ...) : subscript out of bounds
That I think I understand -- searching for "b" is different from demanding the existence of a second element. But then, I created a deeper list:
NOSJ<-rep(list(JSON),3)
sapply(NOSJ,'[[',1)
[,1] [,2] [,3]
a 1 1 1
b 1 1 1
sapply(NOSJ,'[[',2)
$a
[1] 1
$a
[1] 1
$a
[1] 1
And now my head's hurting. Can someone expand on what [[
(or its sapply
method) is doing here?
Upvotes: 6
Views: 480
Reputation: 263301
You could think of sapply and lapply as a for-loop that operates on seq_along(NOSJ) as an index vector.
for( i in seq_along(NOSJ) NOSJ[[i]] .... then use "[[" with the 3rd argument
So the first and second results would be:
> NOSJ[[1]][[1]]
$a
[1] 1
$b
[1] 1
> NOSJ[[2]][[1]]
$a
[1] 1
$b
[1] 1
The difference between sapply
and lapply
is that sapply
attempts to use simply2array
to return a matrix or array if the dimensions of the returned values are all the same (as they are in this case when using 1
, 3
or 5
as the 3rd argument. Quite honestly I do not know why using 2,4,or 6 as the third argument does not return an atomic vector. I thought it should.
Upvotes: 4
Reputation: 59970
sapply(NOSJ,'[[',1)
returns the first list element of each of the lists passed to [[
by sapply
from NOSJ
. Try...
sapply( NOSJ , length )
[1] 6 6 6
Makes sense right? So [[
is operating on the second level lists, the first element of which always contain only a
and b
so are coercible to a matrix. The second element of those lists of 6, always contain only a
.
Upvotes: 3