首页 文章

如何在dplyr管道中进一步处理生成空数据的管道

提问于
浏览
3

此问题发生在 dplyr 版本0.30中 .

我有一个管道 %>%filter 开头 . 有时,此过滤器会将数据框减少为无行 . 有些位于管道的下方,我有一个函数,它使用 if 来改变数据框 . 但是,如果数据帧先前已减少到零行,则此函数会出错 .

例如

data(mtcars)

stupid_function <- function(x){
    if( x == 6){
        return(2*x)
    } else {
        return(x)
    }
}

for(i in 6:10) {

    data <-
        mtcars %>% 
        filter(cyl == i) %>%
        rowwise() %>%
        mutate(carb2 = stupid_function(carb)) %>%
        group_by(carb2) %>%
        summarise(mean(wt))

    print(data)

}

适用于 i = 6 ,但对于 i = 7 失败,例如

反正有没有处理这个问题?我考虑过的两种方法是在中间拆分链,以检查数据在过滤后是否有多行,或者将所有内容包装在 tryCatch 中 .

1 回答

  • 1

    首先,在最新版本的 dplyr (0.4.0)中,过滤器不再崩溃,但是returns its input when the output is 0-sized(参见#782),因此您可能不再有错误 . 特别:

    library(dplyr)
    data(mtcars)
    
    stupid_function <- function(x){
      if(x == 6){
        return(2 * x)
      } else {
        return(x)
      }
    }
    
    for(i in 6:10) {
    
      data <-
        mtcars %>% 
        filter(cyl == i) %>%
        rowwise() %>%
        mutate(carb2 = stupid_function(carb)) %>%
        group_by(carb2) %>%
        summarise(mean(wt))
    
      print(data)
    
    }
    

    返回:

    Source: local data frame [3 x 2]
    
      carb2 mean(wt)
    1     1  3.33750
    2     4  3.09375
    3    12  2.77000
    Source: local data frame [0 x 2]
    
    Variables not shown: carb2 (dbl), mean(wt) (dbl)
    Source: local data frame [4 x 2]
    
      carb2 mean(wt)
    1     2 3.560000
    2     3 3.860000
    3     4 4.433167
    4     8 3.570000
    Source: local data frame [0 x 2]
    
    Variables not shown: carb2 (dbl), mean(wt) (dbl)
    Source: local data frame [0 x 2]
    
    Variables not shown: carb2 (dbl), mean(wt) (dbl)
    Warning messages:
    1: Grouping rowwise data frame strips rowwise nature 
    2: Grouping rowwise data frame strips rowwise nature 
    3: Grouping rowwise data frame strips rowwise nature 
    4: Grouping rowwise data frame strips rowwise nature 
    5: Grouping rowwise data frame strips rowwise nature
    

    您可能还想在 stupid_function 中捕获0大小的输入,如下所示:

    stupid_function <- function(x = NULL) {
      if (is.null(x)) {
        return(0)
      } else if(x == 6) {
        return(2 * x)
      } else {
        return(x)
      }
    }
    

    这预先为x分配NULL并指定0(或者您可以指定NULL)作为返回,如果没有其他任何填充它 .

相关问题