【问题标题】:dplyr group evaluation while simultaneously evaluating single itemsdplyr 分组评估,同时评估单个项目
【发布时间】:2019-05-06 15:47:51
【问题描述】:
library(tidyverse)
df <- tibble(`Roman Numeral` = c(rep("I", 3), rep("II", 3)),
             Letter = c("A", "B", "C", "D", "E", "F"),
             Value = c(10, 5, 22, 3, 25, 7),
             Threshold = rep(20, 6))

df
#> # A tibble: 6 x 4
#>   `Roman Numeral` Letter Value Threshold
#>   <chr>           <chr>  <dbl>     <dbl>
#> 1 I               A         10        20
#> 2 I               B          5        20
#> 3 I               C         22        20
#> 4 II              D          3        20
#> 5 II              E         25        20
#> 6 II              F          7        20

这是我上面的df 数据框。我需要执行涉及组评估的逻辑,同时评估单行。我不知道这是否有意义。让我在下面列出我想要做的事情,希望它是可以理解的。

df.do <- df %>% 
  group_by(`Roman Numeral`) %>% 
  mutate(Violation = **see requested logic**)

下面是所需的输出。如何在tidyverse 中执行这三步逻辑,可能使用dplyr

df.do  # (desired output)
#> # A tibble: 6 x 4
#>   `Roman Numeral` Letter Value Threshold Violation
#>   <chr>           <chr>  <dbl>     <dbl> <logical>
#> 1 I               A         10        20 TRUE
#> 2 I               B          5        20 TRUE
#> 3 I               C         22        20 TRUE
#> 4 II              D          3        20 FALSE
#> 5 II              E         25        20 FALSE
#> 6 II              F          7        20 FALSE
  1. 分别评估每个Roman Numeral
  2. 对于每个Roman Numeral 组;转到带有max() 字母的行并确定(仅针对此行)Value 是否大于Threshold
  3. 如果步骤#2(直接在上面)是TRUE,则为该特定组填充所有Violations,为TRUE,否则填充为FALSE

【问题讨论】:

    标签: r if-statement dplyr


    【解决方案1】:

    因为已经是arranged,所以提取最后一个'Value'

    df %>% 
      group_by(`Roman Numeral`) %>%  
      mutate(Violation = last(Value) >= Threshold)
    # A tibble: 6 x 5
    # Groups:   Roman Numeral [2]
    #  `Roman Numeral` Letter Value Threshold Violation
    #  <chr>           <chr>  <dbl>     <dbl> <lgl>    
    #1 I               A         10        20 TRUE     
    #2 I               B          5        20 TRUE     
    #3 I               C         22        20 TRUE     
    #4 II              D          3        20 FALSE    
    #5 II              E         25        20 FALSE    
    #6 II              F          7        20 FALSE    
    

    如果不是arranged

    df %>% 
      group_by(`Roman Numeral`) %>%  
      mutate(Violation = Value[which.max(factor(Letter))] >= Threshold)
      #or using `dense_rank`
      #mutate(Violation = Value[which.max(dense_rank(Letter))] >= Threshold)
    

    【讨论】:

    • 谢谢@akrun,第一个解决方案有效,但第二个解决方案给了我这个错误Error: Column 'Violation' must be length 3 (the group size) or one, not 0
    • @JasonHunter 抱歉,which.max 需要 factornumeric 列。用factor包装
    猜你喜欢
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    相关资源
    最近更新 更多