簡體   English   中英

dplyr條件匯總功能

[英]dplyr conditional summarise 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)))

pwz (.data,點)中的錯誤:列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復雜得多時。 我不能在摘要中使用case_when嗎? 我的語法是否錯誤? 任何幫助表示贊賞!

編輯:我想我應該指出我有多個條件/函數(只是假設我已經有了,具體取決於變量,其中一些需要均值,總和,最大值,最小值或其他匯總)。

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

注意:

我認為用tidyr::spread “傳播”您的數據可能更有意義,以便每天都有一個溫度,降雨量等列。然后,您可以按常規方式使用summarise

如果您想將所有內容都放在summary函數中,則始終可以執行以下操作。 但這並不比您最初的解決方法復雜:

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

為什么不先在行級別進行計算,然后進行匯總?

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

您可以拆分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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM