2016-11-01 2 views
4

dplyr :: summarize()의 다른 부분에서 조건문을 사용할 수 있습니까?조건부로 dplyr :: summarize()의 다른 부분을 계산할 수 있습니까?

나는 iris 데이터로 작업하고 요약을 출력하고 요청시 Sepal.Length의 평균 만 포함하고자한다고 가정합니다. 그래서 내가 좋아하는 뭔가를 할 수 :

data(iris) 
include_length = T 
if (include_length) { 
    iris %>% 
    group_by(Species) %>% 
    summarize(mean_sepal_width = mean(Sepal.Width), mean_sepal_length = mean(Sepal.Length)) 
} else { 
    iris %>% 
    group_by(Species) %>% 
    summarize(mean_sepal_width = mean(Sepal.Width)) 

} 

그러나 중복 할 필요가 없습니다 있도록 파이프 라인 내에서 조건부 구현하는 방법이?

답변

4

dplyr의 SE 기능 중 .dots 매개 변수를 사용하여 프로그래밍 방식으로 evauluate 할 수 있습니다.

library(dplyr) 

take_means <- function(include_length){ 
    iris %>% 
     group_by(Species) %>% 
     summarize_(mean_sepal_width = ~mean(Sepal.Width), 
        .dots = if(include_length){ 
         list(mean_sepal_length = ~mean(Sepal.Length)) 
        }) 
} 

take_means(TRUE) 
#> # A tibble: 3 × 3 
#>  Species mean_sepal_width mean_sepal_length 
#>  <fctr>   <dbl>    <dbl> 
#> 1  setosa   3.428    5.006 
#> 2 versicolor   2.770    5.936 
#> 3 virginica   2.974    6.588 

take_means(FALSE) 
#> # A tibble: 3 × 2 
#>  Species mean_sepal_width 
#>  <fctr>   <dbl> 
#> 1  setosa   3.428 
#> 2 versicolor   2.770 
#> 3 virginica   2.974 
+1

@ 프랭크 그래, 나는 그것이 어떻게 작동하는지 더 명확하게 결정할 수 없었지만, 그것이 기능으로 더 의미가 있다는 것에 동의하고 편집했다. – alistaire

+1

트릭을해야하는데, 이전 편집을 사용하게 될 것입니다. 감사! –

1

conditional evaluation with magrittr입니다.

가능한 솔루션 :

기본 R에서
library(magrittr) 
library(dplyr) 

data(iris) 
include_length = T 

iris %>% 
    group_by(Species) %>% 
    { if (include_length) {summarize(., mean_sepal_width = mean(Sepal.Width), mean_sepal_length = mean(Sepal.Length))} 
    else {summarize(., mean_sepal_width = mean(Sepal.Width))} 
    } 
+0

나는'mean_sepal_width = mean (Sepal.Width)'를 두 번 쓰는 것을 피하고 싶다고 생각합니다. – Frank

+0

이것은 더 낫지 만, 실제로 사용하는 경우 요약 문은 7 개 또는 8 개의 다른 변수를 계산하므로 불가능할 수도 있지만 이상적으로는 중복을 피할 수 있습니다. –

3

, 당신이 c(x, if (d) y)을 할 수 d의 값에 따라, 두 번째 요소가 포함되거나 결과에서 제외 얻을 것이다. xy은 벡터 또는 목록이 될 수 있습니다. .()list()에 대한 속기

> f(TRUE) 
     Species mw ml 
1:  setosa 3.428 5.006 
2: versicolor 2.770 5.936 
3: virginica 2.974 6.588 
> f(FALSE) 
     Species mw 
1:  setosa 3.428 
2: versicolor 2.770 
3: virginica 2.974 

DT[...] 내부

library(data.table) 
f = function(d) data.table(iris)[, c(
    .(mw = mean(Sepal.Width)), 
    if(d) .(ml = mean(Sepal.Length)) 
), by=Species] 

사용법 : 리턴 표현 목록이기 때문에

이 트릭

는 data.table에서 작동합니다. 파이프를 치고 싶은 이유가있을 수 있지만이 옵션은 고려 가치가 있다고 생각합니다.

0

약간 hackish 방법이 별도로 평균 include_length == TRUE하다면 열을 생성하고, NA

iris %>% 
    group_by(Species) %>% 
    summarise(mean_sepal_length=if(include_length) mean(Sepal.Length) else NA, 
       mean_sepal_width=mean(Sepal.Width)) 

. 문제가있는 경우 사후 처리에서 NA 열을 제거 할 수 있습니다.

관련 문제