首页 文章

dplyr条件汇总函数

提问于
浏览
1

我有这种情况,我需要根据条件得到不同的摘要 function . 例如,使用虹膜,出于某种原因,如果物种是setosa,我想要花瓣宽度的总和,否则我想要花瓣宽度的平均值 .

天真地,我用case_when写了这个,这不起作用:

iris <- tibble::as_tibble(iris)

 iris %>% 
  group_by(Species) %>% 
  summarise(pwz = case_when(
    Species == "setosa" ~ sum(Petal.Width, na.rm = TRUE),
    TRUE                ~ mean(Petal.Width, na.rm = TRUE)))

summarise_impl(.data,dots)出错:列 pwz 必须是长度1(摘要值),而不是50

我最终找到了这样的东西,总结了使用每种方法,然后在变异中挑选我真正想要的那个:

iris %>% 
  group_by(Species) %>% 
  summarise(pws = sum(Petal.Width, na.rm = TRUE),
            pwm = mean(Petal.Width, na.rm = TRUE)) %>% 
  mutate(pwz = case_when(
    Species == "setosa" ~ pws,
    TRUE                ~ pwm)) %>% 
  select(-pws, -pwm)

但是,创建所有这些汇总值并且最后只选择一个值似乎有点尴尬,特别是当我的真实案例更复杂时 . 我可以在汇总中使用case_when吗?我的语法错了吗?任何帮助表示赞赏!

编辑:我想我应该指出我有多个条件/功能(假设我有,取决于变量,一些需要平均值,总和,最大值,最小值或其他摘要) .

5 回答

  • 0

    data.table 这很容易

    library(data.table)
    iris2 <- as.data.table(iris)
    
    iris2[, if(Species == 'setosa') sum(Petal.Width) 
            else mean(Petal.Width)
          , by = Species]
    

    更简洁,但也许不那么清楚

    iris2[, ifelse(Species == 'setosa', sum, mean)(Petal.Width)
          , by = Species]
    

    你可以用 dplyr

    iris %>% 
      group_by(Species) %>% 
      summarise(pwz = if_else(first(Species == "setosa")
                              , sum(Petal.Width)
                              , mean(Petal.Width)))
    

    注意:

    我想_1118574_你的数据 tidyr::spread 可能更有意义,所以每天都有一个温度,降雨量等的列 . 然后你可以用通常的方式使用 summarise .

  • 0

    如果你想把所有东西放在汇总函数中,你总是可以做这样的事情 . 但它并不比原来的解决方案复杂:

    iris %>% 
      group_by(Species) %>% 
      summarise(pwz = 
        sum(Petal.Width, na.rm = TRUE)*
        (1/n()*mean(Species != "setosa") + 
         mean(Species == "setosa")))
    
  • 0

    为什么不首先在行级计算,然后总结?

    iris %>% group_by(Species) %>% mutate(pwz = case_when(
          Species == "setosa" ~ sum(Petal.Width, na.rm = TRUE),
          TRUE                ~ mean(Petal.Width, na.rm = TRUE))) %>% 
          summarize(pwz= first(pwz))
    
    # A tibble: 3 x 2
         Species    pwz
          <fctr>  <dbl>
    1     setosa 12.300
    2 versicolor  1.326
    3  virginica  2.026
    
  • 2
    data(iris)
    library(dplyr)
    
    sum_species <- c('setosa')
    
    iris %>% 
       group_by(Species) %>% 
       summarise(pwz_sum = sum(Petal.Width, na.rm=T), 
                 pwz_mean= mean(Petal.Width, na.rm=T)) %>% 
       ungroup() %>% 
       mutate(pwz = if_else(Species %in% sum_species, pwz_sum, pwz_mean))
    
  • 0

    您可以拆分 data.frame 然后使用 map2_dfr 在每个零件上应用不同的功能并将结果重新拼接在一起:

    library(tidyverse) # purrr & dplyr
    iris %>%
      arrange(Species=="setosa") %>%
      split(.,.$Species=="setosa") %>%
      map2_dfr(c(mean,sum),~.x %>% group_by(Species) %>% summarize_at("Petal.Width",.y))
    
    # # A tibble: 3 x 2
    # Species Petal.Width
    #       <fctr>       <dbl>
    # 1 versicolor       1.326
    # 2  virginica       2.026
    # 3     setosa      12.300
    

相关问题