简体   繁体   English

如何避免矩阵/数据帧作为 R 中的元素通过管道传输 (%>%)

[英]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.我想从 dataframe 创建相关矩阵和协方差矩阵的列表。我尝试使用 magrittr pipe 运算符 ( %>% ) 将 dataframe 输送到列表中,如下例所示。 The problem is that the dataframe itself gets inserted as the first list element.问题是 dataframe 本身作为第一个列表元素插入。 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.我知道 pipe 操作员的默认行为是将 object 注入它通过管道传输到的 function 中的第一个 position。 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?但是,我很想知道是否有一种简单的方法可以将 pipe 矩阵/数据帧转换为列表中的函数,同时避免插入 dataframe 本身?

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: 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

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."根据magrittr的介绍页面“exposition pipe, %$%将左侧 object 中的名称暴露给右侧表达式。” 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

Just add extract to you pipeline to get the result without the first element:只需将extract添加到您的管道中即可获得没有第一个元素的结果:

library(magrittr)

matrix(1:30, ncol = 6) %>% as.data.frame() %>%
list(
    a = list(
        cor(.[,1:3]),
        cov(.[,1:3])
    ),
    b = list(
        cor(.[,4:6]),
        cov(.[,4:6])
    )
) %>%
  extract(-1)
#> $a
#> $a[[1]]
#>    V1 V2 V3
#> V1  1  1  1
#> V2  1  1  1
#> V3  1  1  1
#> 
#> $a[[2]]
#>     V1  V2  V3
#> V1 2.5 2.5 2.5
#> V2 2.5 2.5 2.5
#> V3 2.5 2.5 2.5
#> 
#> 
#> $b
#> $b[[1]]
#>    V4 V5 V6
#> V4  1  1  1
#> V5  1  1  1
#> V6  1  1  1
#> 
#> $b[[2]]
#>     V4  V5  V6
#> V4 2.5 2.5 2.5
#> V5 2.5 2.5 2.5
#> V6 2.5 2.5 2.5

Created on 2022-04-29 by the reprex package (v2.0.1)reprex package (v2.0.1) 创建于 2022-04-29


Addendum附录

An alternative to extract is [ : extract的替代方法是[

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

You could pipe it into an anonymous function to tell R explicitly where to use your dataframe in constructing the output list:您可以将 pipe 转换为匿名 function 以明确告诉 R 在构建 output 列表时在哪里使用您的 dataframe:

library(tidyverse)

matrix(1:30, ncol = 6)  %>%  as.data.frame()  %>%
  (function(df) {
    list(a = list(cor(df[, 1:3]),
                  cov(df[, 1:3])),
         b = list(cor(df[, 4:6]),
                  cov(df[, 4:6])))
  })
#> $a
#> $a[[1]]
#>    V1 V2 V3
#> V1  1  1  1
#> V2  1  1  1
#> V3  1  1  1
#> 
#> $a[[2]]
#>     V1  V2  V3
#> V1 2.5 2.5 2.5
#> V2 2.5 2.5 2.5
#> V3 2.5 2.5 2.5
#> 
#> 
#> $b
#> $b[[1]]
#>    V4 V5 V6
#> V4  1  1  1
#> V5  1  1  1
#> V6  1  1  1
#> 
#> $b[[2]]
#>     V4  V5  V6
#> V4 2.5 2.5 2.5
#> V5 2.5 2.5 2.5
#> V6 2.5 2.5 2.5

It's perhaps one of the limitations of the magrittr pipe that (as far as I'm aware) it seems to be not possible to tell it not to pass LHS in as first argument - unless presumably it's explicitly used in same level of function elsewhere (as in lm examples)?这可能是magrittr pipe 的局限之一(据我所知)似乎不可能告诉它不要将 LHS 作为第一个参数传递 - 除非大概它在其他地方明确用于 function 的同一级别(如lm示例)? As shocking to the system as the migration to the new pipe ( |> ) is, maybe its added elements will overcome this issue in the future.与迁移到新的 pipe ( |> ) 一样令系统震惊,也许它添加的元素将来会解决这个问题。

Created on 2022-04-29 by the reprex package (v2.0.1)reprex package (v2.0.1) 创建于 2022-04-29

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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