简体   繁体   中英

Using dplyr functions inside apply

I want to use dplyr functions inside apply, to every element of a matrix ( BRCK ), which is a matrix of dataframes. I tried something like this:

apply(BRCK, c(1,2), function(x) dplyr::select(x, dplyr::contains("_01_"), 1) %>%
                                dplyr::filter((month(`BRCK[[la, lo]]`) == 1)) %>% 
                                dplyr::select(-contains("BRCK")) 

But it returns

Error: Variable context not set 

And the traceback:

13. stop(cnd) 
12. abort("Variable context not set") 
11. cur_vars_env$selected %||% abort("Variable context not set") 
10. current_vars() 
9. tolower(vars) 
8. dplyr::contains("_01_") 
7. select.list(x, dplyr::contains("_01_"), 1) 
6. dplyr::select(x, dplyr::contains("_01_"), 1) 
5. eval(lhs, parent, parent) 
4. eval(lhs, parent, parent) 
3. dplyr::select(x, dplyr::contains("_01_"), 1) %>% dplyr::filter(x, 
(month(`BRCK[[la, lo]]`) == 1)) %>% dplyr::select(x, -contains("BRCK")) 
2. FUN(newX[, i], ...) 
1. apply(BRCK, c(1, 2), function(x) dplyr::select(x, dplyr::contains("_01_"), 1) %>% dplyr::filter(x, (month(`BRCK[[la, lo]]`) == 1)) %>% 
dplyr::select(x, -contains("BRCK"))) 

BRCK is a very large object, It works with for cycles but I'm trying to replace them with apply functions.

With apply, x is passed as a list in the function and dplyr only deals with dataframe.

apply(BRCK, c(1,2), is.data.frame)
      [,1]  [,2]  [,3]
[1,] FALSE FALSE FALSE
[2,] FALSE FALSE FALSE
[3,] FALSE FALSE FALSE

but :

apply(BRCK, c(1,2), function(x) is.data.frame(x[[1]]))
     [,1] [,2] [,3]
[1,] TRUE TRUE TRUE
[2,] TRUE TRUE TRUE
[3,] TRUE TRUE TRUE

so : 

library(tidyverse)
apply(BRCK, c(1,2), 
      function(x) {
        x[[1]] %>%
          dplyr::select(dplyr::contains("_01_"), 1) %>%
          dplyr::filter(lubridate::month(`BRCK[[la, lo]]`) == 1) %>% 
          dplyr::select(-contains("BRCK")) 
      }
)

One problem is that each element in the loop is a list of a single data frame, not an actual data frame. Compare:

apply(BRCK, c(1,2), function(x) {
  class(x)
}) 

     [,1]   [,2]   [,3]  
[1,] "list" "list" "list"
[2,] "list" "list" "list"
[3,] "list" "list" "list"

apply(BRCK, c(1,2), function(x) {
  class(x[[1]])
}) 

     [,1]         [,2]         [,3]        
[1,] "data.frame" "data.frame" "data.frame"
[2,] "data.frame" "data.frame" "data.frame"
[3,] "data.frame" "data.frame" "data.frame"

I would suggest not using apply loop (rather use lapply on the indices) since the way apply subsets objects and modifies them is not well documented.

I would also suggest not storing data.frames in a matrix. You could store them in a list, and set attributes for the metadata that is implied by the matrix indices.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM