Каков характер периода dplyr "." Справка?

Что указывает период . в следующем dplyr-коде?:

(df <- as.data.frame(matrix(rep(1:5, 5), ncol=5)))
#    V1 V2 V3 V4 V5
#  1  1  1  1  1  1
#  2  2  2  2  2  2
#  3  3  3  3  3  3
#  4  4  4  4  4  4
#  5  5  5  5  5  5

dplyr::mutate_each(df, funs(. == 5))
#       V1    V2    V3    V4    V5
#  1 FALSE FALSE FALSE FALSE FALSE
#  2 FALSE FALSE FALSE FALSE FALSE
#  3 FALSE FALSE FALSE FALSE FALSE
#  4 FALSE FALSE FALSE FALSE FALSE
#  5  TRUE  TRUE  TRUE  TRUE  TRUE

Является ли это сокращением для "всех столбцов"? Является ли этот . конкретным синтаксисом dplyr или является общим синтаксисом R (как обсуждалось здесь)?

Кроме того, почему следующий код приводит к ошибке?

dplyr::filter(df, . == 5)
#  Error: object '.' not found

Ответ 1

Точка используется внутри dplyr главным образом (не исключительно) в mutate_each, summarise_each и do. В первых двух (и их сопоставлениях SE) это относится ко всем столбцам, к которым применяются функции из funs. В do он ссылается на (потенциально сгруппированный) data.frame, поэтому вы можете ссылаться на отдельные столбцы, используя .$xyz для ссылки на столбец с именем "xyz".

Причины, по которым вы не можете запустить

filter(df, . == 5)

заключается в том, что a) filter не предназначен для работы с несколькими столбцами, например, mutate_each, и b) вам нужно будет использовать оператор pipe %>% (первоначально из magrittr).

Однако вы можете использовать его с функцией типа rowSums внутри filter в сочетании с оператором трубы %>%:

> filter(mtcars, rowSums(. > 5) > 4)
Error: Objekt '.' not found

> mtcars %>% filter(rowSums(. > 5) > 4) %>% head()
    lm cyl disp  hp drat    wt  qsec vs am gear carb
1 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
2 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
3 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
4 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
5 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
6 14.3   8  360 245 3.21 3.570 15.84  0  0    3    4

Вы также должны посмотреть файлы справки magrittr:

library(magrittr)
help("%>%")

На странице справки:

Размещение lhs в другом месте по вызову rhsЧасто вам понадобится lhs для вызова rhs в другой позиции, чем первая. Для этого вы можете использовать точку (.) В качестве заполнителя. Например, y %>% f(x, .) эквивалентно f(x, y), а z %>% f(x, y, arg = .) эквивалентно f(x, y, arg = z).

Использование точки для вторичных целейЧасто некоторый атрибут или свойство lhs желательно в вызове rhs в дополнение к самому значению lhs, например. количество строк или столбцов. Совершенно верно использовать многоточечный заполнитель несколько раз в вызове rhs, но по дизайну поведение немного отличается при использовании его внутри вложенных вызовы функций. В частности, если заполнитель используется только в вложенный вызов функции, lhs также будет помещен в качестве первого аргумента! Причиной этого является то, что в большинстве случаев использования читаемый код. Например, iris %>% subset(1:nrow(.) %% 2 == 0)эквивалентно iris %>% subset(., 1:nrow(.) %% 2 == 0), но слегка более компактный. Можно отменить это поведение, включив rhs в фигурных скобках. Например, 1:10 %>% {c(min(.), max(.))}эквивалентно c(min(1:10), max(1:10)).

Ответ 2

Точка имеет особое значение в пределах funs. В этом контексте он ссылается на фиктивный параметр. См. ?funs для описания.

funs создает объект класса "fun_list", который представляет список функций. Каждый аргумент funs - это имя функции, символьная строка, представляющая имя функции или выражение, представляющее тело функции. В последнем случае в выражении, представляющем тело функции, аргумент функции представляется точкой, так что . == 5 относится к функции function(.) . == 5 (хотя dplyr фактически не создает эту функцию, а использует "fun_list" объект).

В этом примере mutate_each будет запускать функцию один раз для каждого столбца, так что это делает то же самое, что и в вопросе, за исключением того, что он также выводит данные каждый раз, когда построенная функция (она фактически не построена, но мы можем подумайте об этом именно так):

> out <- mutate_each(df, funs({print(.); . == 5}))
[1] 1 2 3 4 5
[1] 1 2 3 4 5
[1] 1 2 3 4 5
[1] 1 2 3 4 5
[1] 1 2 3 4 5

В вашем примере filter funs не используется, а filter не работает с объектами "fun_list".

точка имеет другие значения в других контекстах внутри dplyr и может иметь другие значения в других контекстах для других пакетов.