Search code examples
rdplyrpipemagrittr

How to avoid matrix/dataframe being piped (%>%) into list as an element in R


I want to create a list of matrices of correlations and covariances from a dataframe. I tried piping the dataframe into the list, using the magrittr pipe operator (%>%) as shown in the example below. The problem is that the dataframe itself gets inserted as the first list element. I am aware that the pipe operator default behavior is to inject the object into the first position in the function it gets piped into. However, I am curious to know whether there is an easy way to pipe the matrix/dataframe into functions in a list, while avoiding the insertion of the dataframe itself?

Code example:

library(magrittr) # alternatively 'dplyr'

matrix(1:27, ncol = 6) %>% as.data.frame() %>%
list(
    a = list(
        cor(.[,1:3]),
        cov(.[,1:3])
    ),
    b = list(
        cor(.[,4:6]),
        cov(.[,4:6])
    )
)

Output:

[[1]]                          # I want to avoid inserting the 
A data.frame: 4 × 4            # dataframe as an element
V1  V2  V3  V4
<int>   <int>   <int>   <int>
1   5   9   13
2   6   10  14
3   7   11  15
4   8   12  16

$a
   A matrix: 2 × 2 of type dbl
   V1   V2
   V1   1   1
   V2   1   1

   A matrix: 2 × 2 of type dbl
   V1   V2
   V1   1.666667    1.666667
   V2   1.666667    1.666667

$b
   A matrix: 2 × 2 of type dbl
   V3   V4
   V3   1   1
   V4   1   1

   A matrix: 2 × 2 of type dbl
   V3   V4
   V3   1.666667    1.666667
   V4   1.666667    1.666667

Solution

  • So, after I posted, I realised I hadn't really considered to check if there are other operators that might work. According to magrittr's introduction page, "the “exposition” pipe, %$% exposes the names within the left-hand side object to the right-hand side expression." It seems it wasn't necessarily intended for this purpose, but I replaced %>% with %$%, and now it works! (I am still unaware of potentioal drawback to using %$%, so any comments on this is appreciated.)

    library(magrittr)
    
    matrix(1:16, ncol = 4) %>% as.data.frame() %$%
    list(
        a = list(
            cor(.[,1:2]),
            cov(.[,1:2])
        ),
        b = list(
            cor(.[,3:4]),
            cov(.[,3:4])
        )
    )
    
    # $a
    #     A matrix: 2 × 2 of type dbl
    #     V1    V2
    #     V1    1   1
    #     V2    1   1
    
    #     A matrix: 2 × 2 of type dbl
    #     V1    V2
    #     V1    1.666667    1.666667
    #     V2    1.666667    1.666667
    
    # $b
    #     A matrix: 2 × 2 of type dbl
    #     V3    V4
    #     V3    1   1
    #     V4    1   1
    
    #     A matrix: 2 × 2 of type dbl
    #     V3    V4
    #     V3    1.666667    1.666667
    #     V4    1.666667    1.666667