【问题标题】:Numbering identical grouped values with the same number in dplyr在 dplyr 中使用相同编号对相同的分组值进行编号
【发布时间】:2017-05-20 00:45:17
【问题描述】:

我有一个示例数据框:

x <- data.frame(x = c(1, 1, 2, 2, 3, 3, 4, 4, 1), 
                y = c("a", "a", "b", "b", "c", "c", "d", "d", "z"))

我可以很容易地按组获得row_number()

x %>%
    group_by(x) %>%
    mutate(id = row_number())


x y id
1 a  1
1 a  2
2 b  1
2 b  2
3 c  1
3 c  2
4 d  1
4 d  2
1 z  3

然而,我想要x$xx$y的相同组合编号为相同的编号,例如,

x y id
1 a  1
1 a  1
2 b  1
2 b  1
3 c  1
3 c  1
4 d  1
4 d  1
1 z  2

这样c(x$x[1], x&amp;y[1]) == c(x$x[2], x$y[2]) == c(x$x[n], x$y[n] 在新列中的所有值都相同。

如何在dplyr 中做到这一点?

【问题讨论】:

  • 您的意思是与上一行相比相同的组合吗?还是彼此相同(即x$x == x$y)?
  • x %&gt;% group_by_all() %&gt;% filter(n() == 2)
  • @akash87 我用(希望如此!)更好的数据框和更好的问题更新了这个问题。

标签: r dplyr


【解决方案1】:

这是另一个使用factor的解决方案:

## levels=unique(y) is so that levels of y are numbered according to their order of appearance and not alphabetical order
df %>% group_by(x) %>% mutate(id=as.numeric(factor(y,levels=unique(y))))

返回:

  x     y     id
  <dbl> <chr> <dbl>
1     1     a     1
2     1     a     1
3     2     b     1
4     2     b     1
5     3     c     1
6     3     c     1
7     4     d     1
8     4     d     1
9     1     z     2

【讨论】:

    【解决方案2】:

    另一个可能的选择:

    library(dplyr)
    
    x <- data_frame(x = c(1, 1, 2, 2, 3, 3, 4, 4, 1), 
                    y = c("a", "a", "b", "b", "c", "c", "d", "d", "z"))
    
    x %>% 
      group_by(x,y) %>% 
      summarise(y_list = list(y)) %>% 
      group_by(x) %>% 
      mutate(id = row_number()) %>% 
      tidyr::unnest() %>% 
      select(-y_list)
    
    #output
          x     y    id
      <dbl> <chr> <int>
    1     1     a     1
    2     1     a     1
    3     1     z     2
    4     2     b     1
    5     2     b     1
    6     3     c     1
    7     3     c     1
    8     4     d     1
    9     4     d     1
    

    【讨论】:

      【解决方案3】:

      我们可以使用的另一个选项是match

      library(dplyr)
      x %>% 
         group_by(x) %>% 
         mutate(id = match(y, unique(y)))
      # A tibble: 9 x 3
      # Groups: x [4]
      #      x      y    id
      #  <dbl> <fctr> <int>
      #1     1      a     1
      #2     1      a     1
      #3     2      b     1
      #4     2      b     1
      #5     3      c     1
      #6     3      c     1
      #7     4      d     1
      #8     4      d     1
      #9     1      z     2
      

      【讨论】:

        【解决方案4】:
        x          %>% 
        arrange(x) %>% 
        mutate(xid = lag(x$x, default = 1), 
               yid = lag(as.character(x$y), default = "a")) %>% 
        group_by(x) %>%
        mutate(id = cumsum(x != xid | as.character(y) != yid) + 1) %>% 
        mutate(xid = NULL, yid = NULL)
        

        这会产生:

              x      y    id
          <dbl> <fctr> <dbl>
        1     1      a     1
        2     1      a     1
        3     1      z     2
        4     2      b     1
        5     2      b     1
        6     3      c     1
        7     3      c     1
        8     4      d     1
        9     4      d     1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-02
          • 2019-08-12
          • 2014-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-05
          相关资源
          最近更新 更多