【问题标题】:Find first occurence of value in group using dplyr mutate使用 dplyr mutate 在组中查找第一次出现的值
【发布时间】:2015-03-26 07:27:53
【问题描述】:

如何在使用dplyr 的组中找到某个值的第一次出现。

下面的代码给出了想要的结果,但我想知道是否有更短的方法来做到这一点。

另外,我担心group_bymutate 或其他一些函数可能会对行进行隐式重新排列,不知道这是否是个问题?

mtcars   %>% select( cyl, carb) %>% group_by( cyl ) %>%

   mutate( "occurence_of_4" =  carb == 4 )  %>%

   dplyr::arrange( cyl )  %>%

   group_by( cyl, occurence_of_4)  %>%

   mutate( "count" = 1:n(),
           "first_4_in_cyl_group"  = ifelse( occurence_of_4==TRUE & count==1, TRUE, FALSE)) 

变量 first_4_in_cyl_group 是 TRUE 用于每个气缸组中第一次出现的“4”,否则为 FALSE

Source: local data frame [32 x 5]
Groups: cyl, occurence_of_4

   cyl carb occurence_of_4 count first_4_in_cyl_group
1    4    1          FALSE     1                FALSE
2    4    2          FALSE     2                FALSE
3    4    2          FALSE     3                FALSE
4    4    1          FALSE     4                FALSE
5    4    2          FALSE     5                FALSE
6    4    1          FALSE     6                FALSE
7    4    1          FALSE     7                FALSE
8    4    1          FALSE     8                FALSE
9    4    2          FALSE     9                FALSE
10   4    2          FALSE    10                FALSE
11   4    2          FALSE    11                FALSE
12   6    4           TRUE     1                 TRUE
13   6    4           TRUE     2                FALSE
14   6    1          FALSE     1                FALSE
15   6    1          FALSE     2                FALSE
16   6    4           TRUE     3                FALSE
17   6    4           TRUE     4                FALSE
18   6    6          FALSE     3                FALSE
19   8    2          FALSE     1                FALSE
20   8    4           TRUE     1                 TRUE
21   8    3          FALSE     2                FALSE
22   8    3          FALSE     3                FALSE
23   8    3          FALSE     4                FALSE
24   8    4           TRUE     2                FALSE
25   8    4           TRUE     3                FALSE
26   8    4           TRUE     4                FALSE
27   8    2          FALSE     5                FALSE
28   8    2          FALSE     6                FALSE
29   8    4           TRUE     5                FALSE
30   8    2          FALSE     7                FALSE
31   8    4           TRUE     6                FALSE
32   8    8          FALSE     8                FALSE

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以使用!duplicated

    mtcars %>%
      select(cyl, carb) %>%
      group_by(cyl) %>%
      mutate(first_4 = carb == 4 & !duplicated(carb == 4))  %>%
      arrange(cyl)
    

    【讨论】:

    • 喜欢这个 - 对用例(和我的用例)非常有效。当您已经将要查找的第一个项目作为逻辑值时,这真的很干净。
    【解决方案2】:

    一些修改:

    1. 通过在group_by 中创建“occurence_of_4”变量来删除第一个mutate 步骤
    2. ifelse 不需要,因为输出将为“真/假”

      library(dplyr)
      mtcars %>%
           select(cyl, carb) %>%
           group_by(cyl, occurence_of_4= carb==4) %>% 
           arrange(cyl) %>%
           mutate(count= row_number(), 
               first_4_in_cyl_group = occurence_of_4 & count==1)
      

    【讨论】:

      【解决方案3】:

      按 cyl 和 carb 排列就足够了,而不是分组。使用滞后,您可以检查以前的值。

      mtcars 数据库没有 ID 列,因此如果您要重新排列行,可以使用 add_rownames 添加它们(如 cmets 中的 docendodiscimus 建议)。

      mtcars   %>% 
        select( cyl, carb ) %>%
        add_rownames() %>%
        arrange(cyl, carb) %>%
        mutate(
          isfirst = (carb == 4 & (is.na(lag(carb)) | lag(carb) != 4))) %>%
        filter(isfirst)
      

      结果:

      #      rowname cyl carb isfirst
      # 1  Mazda RX4   6    4    TRUE
      # 2 Duster 360   8    4    TRUE
      

      【讨论】:

      • 您缺少重现所需结果所需的分组,不是吗?
      • @docendodiscimus 我不确定为什么要使用分组。我可能不理解所需的输出,但按照我的理解安排应该足够了。
      • 将您的代码输出与所需结果的最后一列进行比较。您的代码生成的 TRUE 条目比预期的要多
      • 如果按cyl和carb排列就可以了。
      • 你是对的。 (+1) 顺便说一句,您可以在 dplyr 链中使用 add_rownames("id")
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多