如何解决与管道运算符和 [ 选择器一起使用时,为什么 colnames 函数会生成小标题而不是矢量?
问题:当 colnames
函数与管道运算符 %>%
和 [
选择器一起使用时,为什么会生成小标题?
示例:给定以下小标题:
library(tidyverse)
x <- tribble(
~a,~b,1,1
)
问题:当与管道运算符和 [
选择器一起使用时,colnames 函数会生成一个 tibbe:
x %>% colnames(.)[1]
#> # A tibble: 2 x 1
#> a
#> <dbl>
#> 1 NA
#> 2 NA
colnames(x)[1]
#> [1] "a"
解决方法
管道将左侧插入到右侧 main 函数的第一个参数中,在本例中为 [ 。那就是这三个是一样的:
x %>% colnames(.)[1]
x %>% `[`(colnames(.),1)
x %>% `[`(.,colnames(.),1)
最后一个是相同的,因为如果主函数的参数之一是点,它不会插入左侧。
要防止它插入点,请使用 {...}
x %>% { colnames(.)[1] }
或使用:
x %>% colnames %>% .[1]
或使用 dplyr::first
或 dplyr::slice_head(n = 1) 或 dplyr::nth(1) 或 purrr::pull(1)
或 magrittr::extract(1)
或 head(1)
x %>% colnames %>% first
,
因为 %>%
自动插入 .
作为右侧的第一个参数,除非 .
已经用作右侧的顶级参数-手边。
您的右手边是 colnames(.)[1]
— 而 .
不是此处的顶级参数。实际上,表达式 colnames(.)[1]
完全等同于
`[`(colnames(.),1)
所以这个表达式的顶级参数是colnames(.)
和1
。 .
也不是。所以 %>%
将您的表达式转换为
`[`(x,colnames(x),1)
再次等价于
x[colnames(x),1]
这种表达实际上没有意义,并且恰好导致了您所观察到的。
为避免 .
自动插入,您可以将表达式包装到 {…}
中,如 akrun 所示。或者您可以将复合表达式拆分为其组成部分:
x %>% colnames() %>% `[`(1L)
,
我们可以在 first
之后使用 colnames
x %>%
colnames %>%
first
#[1] "a"
或者在 {}
内阻塞整个表达式以作为单个表达式求值并避免运算符的优先级
x %>%
{colnames(.)[1]}
#[1] "a"
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。