найти сумму квадратов с помощью трубы - PullRequest
3 голосов
/ 04 октября 2019

Если x <- 1:5, то следующее:

sum(x^2)

возвращает 55, правильный ответ. Однако, если используется оператор канала:

x %>% sum(.^2)

, тогда возвращается 70 (что является суммой x^2 и суммой x).

Хотя есть несколько способов обойти это, я в основном хотел бы знать, что происходит.

Ответы [ 3 ]

5 голосов
/ 04 октября 2019

Интересный вопрос!

То, что происходит, заключается в том, что канал автоматически передает свой аргумент в качестве первого аргумента следующему выражению, поэтому x %>% sum(.^2) эквивалентно sum(x, x^2).

Я более привык работать с %>% в контексте фрейма данных / tidyverse, где первый аргумент каждого из глаголов tidyverse (например, mutate, filter, select)сам фрейм данных:

data.frame(x) %>% dplyr::mutate(y=sum(x^2))
1 голос
/ 04 октября 2019

Более обобщенный подход может состоять в том, чтобы создать свою собственную функцию, а затем направить ее к ней.

Например,

SqSum <- function(x){
  sum(x^2)
}
x %>% SqSum()

Теперь мы можем использовать ту же структуру для выполнения любых операций, которые мы выполняем. want.

Также обратите внимание, что мы избегаем многих ошибок, которые остались бы незамеченными. Например, использование x %>% SqSum(.x) вернет ошибку, поскольку мы указали только один аргумент для нашей функции. Это оборонительное стиль программирования может быть полезным.

Что касается объяснения, Бен прибил его ...

1 голос
/ 04 октября 2019

Вы можете сделать:

x %>%
.^2 %>%
 sum()

[1] 55

Работает, так как строка sum() принимает вывод предыдущей строки (.^2) в качестве ввода. С другой стороны, в вашем первоначальном подходе строка sum() принимает в качестве входных данных как исходный вектор, так и его мощность и суммирует их вместе.

Альтернативно:

x %>%
 {sum(.^2)}

Здесь, используя фигурные скобки, содержимое левой стороны (LHS), которое является исходным вектором в вашем случае, не используется в качестве первого аргумента функции sum() (как объяснено @Ben Bolker).

...