lapply with “$” function

后端 未结 2 1480
一个人的身影
一个人的身影 2020-12-13 04:18

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

2条回答
  •  南方客
    南方客 (楼主)
    2020-12-13 04:34

    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
    

提交回复
热议问题