R의 높은 레벨 기능 - 공식 작곡 연산자 또는 카레 기능이 있습니까?
-
19-09-2019 - |
문제
r에서 Compose 연산자를 만들 수 있습니다.
`%c%` = function(x,y)function(...)x(y(...))
다음과 같이 사용하려면 :
> numericNull = is.null %c% numeric
> numericNull(myVec)
[2] TRUE FALSE
그러나 R의 카레와 같은 이런 종류의 기능 및 기타 작업을 수행하기위한 공식 기능 세트가 있는지 알고 싶습니다. 대부분 내 코드의 괄호, 기능 키워드 등의 수를 줄이는 것입니다.
내 카레 기능 :
> curry=function(...){
z1=z0=substitute(...);z1[1]=call("list");
function(...){do.call(as.character(z0[[1]]),
as.list(c(eval(z1),list(...))))}}
> p = curry(paste(collapse=""))
> p(letters[1:10])
[1] "abcdefghij"
이것은 예를 들어 집계에 특히 좋습니다.
> df = data.frame(l=sample(1:3,10,rep=TRUE), t=letters[1:10])
> aggregate(df$t,df["l"],curry(paste(collapse="")) %c% toupper)
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
나는 다음과 같이 훨씬 더 우아하고 편집 할 수 있습니다.
> aggregate(df$t, df["l"], function(x)paste(collapse="",toupper(x)))
l x
1 1 ADG
2 2 BCH
3 3 EFIJ
기본적으로 알고 싶습니다. 이미 R에 대해 완료 되었습니까?
해결책
R의 기능 프로그래밍을위한 표준 장소는 이제 functional
도서관.
도서관에서 :
기능 : 카레, 작곡 및 기타 고차 기능
예시:
library(functional)
newfunc <- Curry(oldfunc,x=5)
크랜 :https://cran.r-project.org/web/packages/functional/index.html
추신 :이 라이브러리는 ROxigen
도서관.
다른 팁
이 두 기능은 실제로 존재합니다 그만큼 roxygen
패키지 (여기에서 소스 코드를 참조하십시오Peter Danenberg의) (원래는 R-Help에 대한 바이런 엘리스의 솔루션):
Curry <- function(FUN,...) {
.orig = list(...);
function(...) do.call(FUN,c(.orig,list(...)))
}
Compose <- function(...) {
fs <- list(...)
function(...) Reduce(function(x, f) f(x),
fs,
...)
}
사용의 사용법에 유의하십시오 Reduce
기능, R.에서 기능 프로그래밍을 시도 할 때 매우 유용 할 수있는 기능을 참조하십시오. 자세한 내용은 다음과 같은 다른 기능을 다루십시오. Map
그리고 Filter
).
그리고 카레의 예 (이 사용에서 약간 다름) :
> library(roxygen)
> p <- Curry(paste, collapse="")
> p(letters[1:10])
[1] "abcdefghij"
다음은 유용성을 보여주는 예입니다 Compose
(문자에 세 가지 기능 적용) :
> Compose(function(x) x[length(x):1], Curry(paste, collapse=""), toupper)(letters)
[1] "ZYXWVUTSRQPONMLKJIHGFEDCBA"
그리고 마지막 예제는 다음과 같이 작동합니다.
> aggregate(df[,"t"], df["l"], Compose(Curry(paste, collapse=""), toupper))
l x
1 1 ABG
2 2 DEFH
3 3 CIJ
마지막으로, 여기에 똑같은 일을하는 방법이 있습니다. plyr
(쉽게 수행 할 수 있습니다 by
또는 aggregate
이미 표시된대로) :
> library(plyr)
> ddply(df, .(l), function(df) paste(toupper(df[,"t"]), collapse=""))
l V1
1 1 ABG
2 2 DEFH
3 3 CIJ
변수의 '이름'이 정확하게 통과되기를 원한다면보다 복잡한 접근 방식이 필요합니다.
예를 들어, 그렇다면 plot(rnorm(1000),rnorm(1000))
그러면 X- 및 Y- 축에 멋진 레이블을 얻을 수 있습니다. 이것의 또 다른 예입니다 data.frame
> data.frame( rnorm(5), rnorm(5), first=rpois(5,1), second=rbinom(5,1,0.5) )
rnorm.5. rnorm.5..1 first second
1 0.1964190 -0.2949770 0 0
2 0.4750665 0.8849750 1 0
3 -0.7829424 0.4174636 2 0
4 1.6551403 1.3547863 0 1
5 1.4044107 -0.4216046 0 0
Data.Frame이 열에 유용한 이름을 할당 한 것은 아닙니다.
일부 카레 구현은이를 제대로 수행하지 않아서 읽을 수없는 열 이름과 플롯 레이블로 이어질 수 있습니다. 대신, 나는 이제 다음과 같은 것을 사용합니다.
Curry <- function(FUN, ...) {
.orig = match.call()
.orig[[1]] <- NULL # Remove first item, which matches Curry
.orig[[1]] <- NULL # Remove another item, which matches FUN
function(...) {
.inner = match.call()
.inner[[1]] <- NULL # Remove first item, which matches Curry
do.call(FUN, c(.orig, .inner), envir=parent.frame())
}
}
이것은 매우 복잡하지만 맞다고 생각합니다. match.call
모든 args를 잡을 것이며, 어떤 표현이 Args를 정의했는지 완전히 기억합니다 (이것은 좋은 레이블에 필요합니다). 문제는 너무 많은 args를 잡는다는 것입니다. ...
또한 FUN
. 또한 호출되는 함수의 이름을 기억합니다.Curry
).
따라서 우리는이 첫 두 항목을 삭제하고 싶습니다. .orig
~하도록 하다 .orig
실제로 그냥 일치합니다 ...
논쟁. 그것이 우리가하는 이유입니다 .orig[[1]]<-NULL
두 번 - 매번 항목을 삭제하고 다른 모든 것을 왼쪽으로 이동시킵니다.
이것은 정의를 완료하고 이제 다음을 수행 할 수 있습니다. 바로 그거죠 위와 동일합니다
Curry(data.frame, rnorm(5), rnorm(5) )( first=rpois(5,1) , second=rbinom(5,1,0.5) )
최종 메모 envir=parent.frame()
. '.inner'또는 '.orig'라는 외부 변수가 있으면 문제가 없도록하기 위해 이것을 사용했습니다. 이제 모든 변수는 카레가 호출되는 장소에서 평가됩니다.