Выберите функцию из набора имен функций и соедините с ней канал


Предположим, у меня есть tibble (или фрейм данных, что угодно) со списком имен функций. Скажем, что-то вроде:

functions <- tibble(c("log()", "log10()", "sqrt()"))

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

data %>% functions[[1]]

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

Заранее благодарю.

3 5

3 ответа:

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

functions <- c("log", "log10", "sqrt")

Нет никакой причины помещать их в тиббл, и если вы это сделаете, вам понадобится functions[[1]][1], как упоминает @ Aaghaz-Hussain.

seq(10) %>% get(functions[1])()
# [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595 1.9459101 2.0794415 2.1972246 2.3025851

get извлекает определение функции из ее имени в виде строки, после этого это простой канал, за исключением того, что вам нужно убедиться, что () явны как seq(10) %>% get(functions[[1]]) он будет интерпретирован как seq(10) %>% get(.,functions[[1]])

1) совпадение.fun используйте match.fun, чтобы превратить строку в функцию. Точка, ., необязательна.

functions <- c("log", "log10", "sqrt")
10 %>% match.fun(functions[2])(.)
## [1] 1

1a) это также может быть записано как:

10 %>% (match.fun(functions[2]))
## [1] 1

1b) или

10 %>% (functions[2] %>% match.fun)
## [1] 1

2) Делай.звоните do.call также будет работать:

10 %>% { do.call(functions[2], list(.)) }
## [1] 1

3) call / eval Обычно eval не одобряется, но он формирует другую альтернативу:

10 %>% call(functions[2], .) %>% eval
## [1] 1

В дополнение к уже приведенным ответам стоит отметить, что в R-списках можно хранить практически все, даже функции. Так что это тоже работает:

funs <- list(log, log10, sqrt)
f <- funs[[1]]
2 %>% f