dplyr条件汇总函数

时间:2018-04-25 20:17:31

标签: r dplyr

我遇到这种情况,根据条件,我需要一个不同的摘要功能。 例如,使用虹膜,出于某种原因,如果物种是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 :(得分:2)

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)))

注意:

我认为传播&#34;传播可能更有意义。您的数据为tidyr::spread,以便每天都有一个温度,降雨量等列。然后您可以按常规方式使用summarise

答案 1 :(得分:0)

如果您想将所有内容都放在摘要功能中,您可以随时执行此类操作。但它并不比原来的解决方案复杂:

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

答案 2 :(得分:0)

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

import org.apache.flink.contrib.streaming.DataStreamUtils;

DataStream<Tuple2<String, Integer>> myResult = ...
Iterator<Tuple2<String, Integer>> myOutput = DataStreamUtils.collect(myResult)

答案 3 :(得分:0)

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))

答案 4 :(得分:0)

您可以拆分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 在每个部分上应用不同的功能并将结果重新拼接在一起:

substitute