Значение ошибки с помощью.стенография внутри функции dplyr - PullRequest
0 голосов
/ 06 июня 2018

Я получаю ошибку 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))

Я делаю это как часть гораздо большего потока конвейерных шагов, поэтому я не могу просто сделать 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

Но когда я пытаюсь сделать то же самое с сокращением ., я получаю эту ошибку:

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

Как я уже сказал, делать это первым способом хорошо, но я хотел бы понять ошибку, потому что я пишу много многошагового кода.

1 Ответ

0 голосов
/ 11 июня 2018

Как отметил @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"))

Вот предложение, которое позволит полностью избежать этой проблемы:

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