使用错误的含义。dplyr 函数中的简写

cam*_*lle 8 r dplyr magrittr

我收到一个dplyr::bind_rows错误。这是一个非常微不足道的问题,因为我可以轻松绕过它,但我想了解错误消息的含义。

我有新英格兰各州一些人口群体的以下数据,我想绑定这些相同值的副本,并将名称更改为“新英格兰”,以便我可以按名称分组并将它们加起来,给我各个州的价值,以及该地区的整体价值。

df <- structure(list(name = c("CT", "MA", "ME", "NH", "RI", "VT"), 
        estimate = c(501074, 1057316, 47369, 76630, 141206, 27464)),
        class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L))
Run Code Online (Sandbox Code Playgroud)

我这样做是作为更大的管道步骤流程的一部分,所以我不能只做bind_rows(df, df %>% mutate(name = "New England")). dplyr.从一个函数传输到下一个函数的数据帧提供了方便的速记,但我不能使用它以我喜欢的方式将数据帧绑定到自身。

什么的工作,让我我想要的输出:

library(tidyverse)

df %>%
  # arbitrary piped operation
  mutate(name = str_to_lower(name)) %>%
  bind_rows(mutate(., name = "New England")) %>%
  group_by(name) %>%
  summarise(estimate = sum(estimate))
#> # A tibble: 7 x 2
#>   name        estimate
#>   <chr>          <dbl>
#> 1 ct            501074
#> 2 ma           1057316
#> 3 me             47369
#> 4 New England  1851059
#> 5 nh             76630
#> 6 ri            141206
#> 7 vt             27464
Run Code Online (Sandbox Code Playgroud)

但是当我尝试用.速记做同样的事情时,我得到了这个错误:

df %>%
  mutate(name = str_to_lower(name)) %>%
  bind_rows(. %>% mutate(name = "New England"))
#> Error in bind_rows_(x, .id): Argument 2 must be a data frame or a named atomic vector, not a fseq/function
Run Code Online (Sandbox Code Playgroud)

就像我说的,用第一种方式做就可以了,但我想了解这个错误,因为我写了很多多步管道代码。

Moo*_*per 8

正如@aosmith 在评论中指出的,这是由于magrittr在这种情况下解析点的方式:

来自?'%>%'

使用点占位符作为 lhs

当点用作 lhs 时,结果将是一个函数序列,即一个将整个右侧链依次应用于其输入的函数。

为避免触发这种情况,对 lhs 上的表达式的任何修改都将执行以下操作:

df %>%
  mutate(name = str_to_lower(name)) %>%
  bind_rows((.) %>% mutate(name = "New England"))

df %>%
  mutate(name = str_to_lower(name)) %>%
  bind_rows({.} %>% mutate(name = "New England"))

df %>%
  mutate(name = str_to_lower(name)) %>%
  bind_rows(identity(.) %>% mutate(name = "New England"))
Run Code Online (Sandbox Code Playgroud)

这是一个完全避免这个问题的建议:

df %>%
  # arbitrary piped operation
  mutate(name = str_to_lower(name)) %>%
  replicate(2,.,simplify = FALSE) %>%
  map_at(2,mutate_at,"name",~"New England") %>%
  bind_rows

# # A tibble: 12 x 2
#    name        estimate
#    <chr>          <dbl>
#  1 ct            501074
#  2 ma           1057316
#  3 me             47369
#  4 nh             76630
#  5 ri            141206
#  6 vt             27464
#  7 New England   501074
#  8 New England  1057316
#  9 New England    47369
# 10 New England    76630
# 11 New England   141206
# 12 New England    27464
Run Code Online (Sandbox Code Playgroud)