Подтвердить что ты не робот

Как конкатенировать/составить функции в R?

Часто я хочу сделать что-то вроде следующего:

sapply(sapply(x, unique),sum)

Который я могу также написать как:

sapply(x, function(y) sum(unique(y)))

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

sapply(x, concat(sum,unique))

И concat просто объединяет две функции, тем самым создает новый, который выполняется один за другим.

4b9b3361

Ответ 1

Для этого вы можете использовать функцию Compose в пакете functional, доступную в CRAN.:

library(functional)
sapply(x, Compose(unique,sum))

Ответ 2

Подробнее о Curry'ing and Composing

Существует partial в пакете pryr, который примерно совпадает с Curry в пакете functional, но в другом путь.

(Curry создает список аргументов и передает его в do.call. partial буквально создает новую функцию, которая вызывает первую функцию с установленными аргументами по умолчанию.)

В этой дискуссии в R-devel, Люк Тирни указывает на некоторые проблемы с Curry (" Это имеет совершенно другое поведение в отношении оценки/ленивой оценки, чем аналогичная анонимная функция. Кроме того, do.call имеет довольно странный аспект, так что он касается того, как он взаимодействует с функциями sys.xyz, и не делает то, что вы хотите во многих случаях мне о том, когда quote = FALSE, как и по умолчанию. создайте больше проблем, чем решает.). Эти проблемы (как бы редко они не возникали) не связаны с partial.

Другие подходы к применению карри/частичной функции:

wargs в пакете dostats (аналогично partial, но имеет что-то своеобразное:

wargs(mean, na.rm=TRUE)(c(1:5, NA), na.rm=FALSE)
# this works and gives NA as answer, so na.rm=FALSE overrides na.rm=TRUE
# with partial, this would result in an error:
#### formal argument "na.rm" matched by multiple actual arguments

В пакете operators есть %but%, но он не работает с универсальными функциями. Итак...

df <- data.frame(a=c(1:5,NA), b=c(NA, 2:6))
sapply(df, mean %but% list(na.rm=TRUE))
#  a  b 
# NA NA 
# ... but2
sapply(df, sd %but% list(na.rm=TRUE))
#        a        b 
# 1.581139 1.581139 

И он имеет отдельный механизм для установки логических аргументов:

# from the help page
grep %but% "pf"     # grep, with perl and fixed set to TRUE

Как и для компоновки, существуют одинаково названные (но разные) версии в pryr и dostats: compose и %.% - и оба они отличаются от functional:::Compose.

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

Ответ 3

Использование magrittr

Если we require(magrittr), то мы можем

sapply(x, . %>% unique %>% sum)

или даже

x %>% sapply(. %>% unique %>% sum).

Ответ 4

Вы можете вырасти самостоятельно:

myfunc <- function(y) {
    yu <- unique(y)
    ys <- sum(yu)
    return(ys)
    }

Тогда

sapply(x, myfunc)