В языке R есть новый встроенный оператор конвейера, начиная с версии R 4.1: |>

%>% это канал, который знает большинство пользователей R. Родом из пакет magrittr, теперь он используется и во многих других пакетах. (Если вам интересно, откуда взялось название magrittr, это отсылка к бельгийскому художнику Рене Магритту и одной из его картин, Предательство образов, который говорит по-французски: «Это не трубка».)

Вот несколько тривиальный пример с использованием %>% pipe с набором данных mtcars и парой функций dplyr. Этот код фильтрует данные для строк с более чем 25 миль на галлон и упорядочивает результаты по убыванию миль на галлон:

library(dplyr)
mtcars %>%
filter(mpg > 25) %>%
arrange(desc(mpg))

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

mtcars <- filter(mtcars, mpg > 25)
mtcars <- arrange(mtcars, desc(mpg))

# OR

arrange(filter(mtcars, mpg > 25), desc(mpg))

Запустите R 4.1 в Docker

Если вы еще не готовы установить R 4.1 в своей системе, один из простых способов опробовать новый канал – запустить R 4.1 внутри контейнера Docker. Я даю полные общие инструкции в «Как запустить R 4.0 в Docker» – единственная новая часть – это использование образа Docker с R 4.1. По сути, вам нужно загрузить и установить Docker, если у вас его еще нет, запустить Docker, а затем запустить приведенный ниже код в окно терминала (не консоль R).

docker run -e PASSWORD=your_password_here --rm -p 8787:8787 -v /path/to/local/directory:/home/rstudio/morewithr rocker/tidyverse:4.1.0

В -v /path/to/local/directory:/home/rstudio/morewithr Часть кода создает том, соединяющий каталог внутри контейнера Docker с файлами в локальном каталоге. Это необязательно, но может быть очень удобно.

Новая труба в R 4.1

Зачем R нужна новая встроенная труба, когда magrittr уже поставляет ее? Он сокращает внешние зависимости, поэтому разработчикам не нужно полагаться на внешний пакет для такой ключевой операции. Также, встроенная труба может быть быстрее.

Новые базовые каналы R и magrittr работают в основном одинаково, но есть важное различие при работе с функциями, которые не имеют синтаксиса, удобного для каналов. Под «дружественным к конвейеру» я подразумеваю, что первым аргументом функции, вероятно, будет значение, которое будет передано из конвейерного кода. Например, str_detect() функция в пакете stringr использует строка для поиска в качестве первого аргумента и образец для поиска как второй аргумент. Это хорошо работает с трубами. Например:

library(stringr)
# add column name with car model number
mtcars$model <- rownames(mtcars)
# filter for all cars that start with "F"
mtcars %>%
filter(str_detect(model, "^F"))

Напротив, grepl() в базе R имеет противоположный синтаксис. Его первый аргумент – это шаблон а второй аргумент – это строка для поиска. Это создает проблемы для трубы.

У канала maggritr есть решение для синтаксиса, не дружественного к каналу, которое заключается в использовании . точка для представления передаваемого значения:

mtcars %>%
filter(grepl("^F", .[["model"]]))

Теперь посмотрим, как работает основная R-труба. Он отлично запускает код строки:

mtcars |>
dplyr::filter(stringr::str_detect(model, "^F"))

Однако он не использует точку для обозначения того, что передается по конвейеру, поэтому этот код будет нет Работа:

mtcars |>
filter(grepl("^F", .[["model"]]))

По крайней мере, на данный момент нет специального символа для представления передаваемого значения.

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

Часто это не самый эффективный вариант, но вы можете создать свою собственную функцию, используя исходную функцию, и просто переключать аргументы или иным образом переделывать код, чтобы первый аргумент стал дружественным к конвейеру. Например, мой новый mygrepl функция имеет фрейм данных в качестве первого аргумента, что часто является способом запуска каналов:

mygrepl <- function(mydf, mycolumn, mypattern) {
mydf[grepl(mypattern, mydf[[mycolumn]]),]
}

mtcars |>
mygrepl("model", "^F")

Сокращение функций R 4.1

Кстати, о функциях. В R 4.1 появилась еще одна интересная новая функция. Теперь вы можете использовать символ обратной косой черты как сокращение от слова «функция» в R 4.1. Я думаю, что это было сделано в основном для так называемых анонимных функций, т. Е. Функций, которые вы создаете в коде, у которых нет собственных имен. Но работает для всех функций. Вместо создания новой функции с function(), теперь вы можете использовать (). Например:

mygrepl2 <- (mydf, mycolumn, mypattern) {
mydf[grepl(mypattern, mydf[[mycolumn]]),]
}

mtcars |>
mygrepl2("model", "^F")

R трубы и функции без аргументов

И, наконец, последнее замечание о новой встроенной трубе. Если вы подключаетесь к функции без аргументов, круглые скобки по желанию с трубкой маггритра, но обязательный с основной трубой R. Оба они работают на %>% :

#Works:
mtcars %>%
tail()

#Works:
mtcars %>%
tail

Но только первая версия работает с |> :

#Works:
mtcars |>
tail()

#Doesn't work
mtcars |>
tail

Вы можете увидеть новый конвейер в действии, а также запуск R 4.1 в контейнере Docker на видео в верхней части этой статьи.

Чтобы узнать больше советов и руководств по R, перейдите в мою Делайте больше со страницей R.

Авторские права © 2021 IDG Communications, Inc.


#Используйте #новую #трубу #встроенную

Source link