2017-03-03 68 views
1

在函數調用中我有一個複雜的dplyr結構。輸入是一個數據幀,它可以有一個名爲s的額外列。如果此欄可用,我想按此欄分組標準分組。 目前,我通過if語句檢查列是否在數據框中並進行不同的分組來解決它。分組後,我對這兩種數據都有相同的代碼。在dplyr中分組並丟失列

有沒有更好的方法來做到這一點?在我原來的函數中,我在summarise函數中計算了幾個變量,我不想單獨維護這兩個部分。

這裏是一個例子。

library(dplyr) 
df1 <- data.frame(s=rep(c('a','b'), each=10), 
        p=rep(letters[1:5], 4), 
        v=runif(20)) 
df2 <- data.frame(p=rep(letters[1:5], each=4), 
        v=runif(20)) 

avgP <- function(df) { 
    if('s' %in% names(df)) { 
    df %>% 
     group_by(s, p) %>% 
     summarise(avg=mean(v)) 
    } else { 
    df %>% 
     group_by(p) %>% 
     summarise(avg=mean(v)) 
    } 
} 

avgP(df1) 
avgP(df2) 

我首選的方案會是這樣group_by只是僅由p忽略丟失的列和意志集團當我df2工作。

+0

是變量設置在每個數據一樣嗎? (當然除了's')?也許使用SE – Sotos

+0

SE是什麼意思?是的,他們基本上是一樣的。 – drmariod

+2

[看看這個鏈接](https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html)。另外@ akrun的答案使用SE – Sotos

回答

3

我們可以使用intersect

avgP1 <- function(df){ 
    df %>% 
    group_by_(.dots = intersect(names(df), c("s", "p"))) %>% 
    summarise(avg=mean(v)) 
} 

avgP1(df1) 
avgP1(df2) 
+1

哇,這是一個非常好的解決方案。如果分組列完全缺失,我可以以類似的方式使用它嗎?要分組或不分組... ...所以要說:-) – drmariod

+0

@drmariod在當前的設置中,如果沒有's'或'p'列,它會給出整個'v'的平均值,即df3 < - df2 [-1]; avgP1(df3)#avg 1 0.5880442; mean(df3 $ v) #[1] 0.5880442' ' – akrun

+1

這很完美。我並不知道所有這些'_'函數,我只是認爲它們可以幫助命名衝突......在我原來的函數中,我還使用'tidyr :: gather',現在切換到'tidyr :: gather_'我有更多的可能性。再次感謝! – drmariod