代码之家  ›  专栏  ›  技术社区  ›  HSJ

如何在r中按顺序重新编号组id?

  •  1
  • HSJ  · 技术社区  · 6 年前

    我正在尝试使用 dplyr 在里面 R 是的。 数据框中有五列,如下所示。

    ## Load package if necessary
    library(tidyverse)
    
    ## Set data frame
    df <- data.frame(
        hid=c(10001,10001,10001,10001,10002,10002,10002,10002,10002,
              10003,10003,10003,10003,10003,10003,10004,10004,10004,10004,10004),
        mid=c(1,2,3,4,1,2,3,4,5,1,2,3,4,5,6,1,2,3,4,5),
        tmc=c(010,01010,0,01020,010,010,010,010,010,010,010,010,0,010,010,010,0,01010,010,01010),
        thc=c(010,01010,0,02030,010,020,020,020,030,010,010,010,0,020,030,010,0,02020,030,04040),
        mdc=c(000,01010,0,02020,000,010,010,010,010,000,000,010,0,010,020,000,0,02020,010,01010),
        itc=c(010,01010,0,02020,020,020,020,020,020,010,010,010,0,020,020,010,0,02020,020,02020)
        )
    

    为按某些列分组的每一行提供唯一的ID: tmc 我是说, thc 我是说, mdc itc 是的。

    ## Add unique id grouped by tmc, thc, mdc and itc
    df.id <- df %>% mutate(id=as.numeric(interaction(tmc,thc,mdc,itc)))
    

    因为它没有顺序id,所以我需要重命名它。 但是,我找不到解决办法。条件是:

    • 如果 TMC公司 我是说, 泰铢 我是说, MDC公司 国贸中心 都是0, id 设置为 0 (我不知道原因,但是 interaction 给予 1 在我的数据帧中这样记录)
    • 其他id应该按顺序重命名,但需要保留其组。(如果 身份证件 S设置为 4,8,2,2,8 ,应重命名为 1,2,3,3,2 )

    下面的脚本显示了我目前正在做的事情。 身份证件 是从 相互作用 函数,但我需要获得 id.desired 列。

    ## Replace unique id sequentially
    ## IT DOES NOT GIVE DESIRED OUTPUT
    # df.id %>% group_by(id) %>% mutate(id2=seq_along(id))
    
    ## Desired id is shown in `id.desired`
    ## `id` is the ones obtained from `interaction` function, which are not set sequentially
         hid   mid   tmc   thc   mdc   itc    id   id.desired
       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
     1 10001     1    10    10     0    10   166     1
     2 10001     2  1010  1010  1010  1010   595     2
     3 10001     3     0     0     0     0     1     0
     4 10001     4  1020  2030  2020  2020   796     3
     5 10002     1    10    10     0    20   326     4
     6 10002     2    10    20    10    20   362     5
     7 10002     3    10    20    10    20   362     5
     8 10002     4    10    20    10    20   362     5
     9 10002     5    10    30    10    20   366     6
    10 10003     1    10    10     0    10   166     1
    11 10003     2    10    10     0    10   166     1
    12 10003     3    10    10    10    10   198     7
    13 10003     4     0     0     0     0     1     0
    14 10003     5    10    20    10    20   362     5
    15 10003     6    10    30    20    20   398     8
    16 10004     1    10    10     0    10   166     1
    17 10004     2     0     0     0     0     1     0
    18  1004     3  1010  2020  2020  2020   791     9
    19 10004     4    10    30    10    20   366     6
    20 10004     5  1010  4040  1010  2020   767    10
    

    有什么建议吗? 我更喜欢用 DPLYR公司 在这次行动中。

    我在前一个问题中收到了一些建议,但是在这个例子中它的结构不同( dummy 当前数据帧中不存在字段。 How to renumber result of intersection/group_indices in R?

    3 回复  |  直到 6 年前
        1
  •  2
  •   www    6 年前

    使用 tidyverse .注意,我没有使用 interaction 功能。相反,我用了 group_indices 功能来自 dplyr 创建组索引,然后转换为因子并根据列中的出现顺序更改级别。 df2 是最终输出。

    library(tidyverse)
    
    df2 <- df %>%
      filter_at(vars(tmc, thc, mdc, itc), any_vars(. != 0)) %>%
      mutate(id = group_indices(., tmc, thc, mdc, itc)) %>%
      mutate(id = as.numeric(factor(id, levels = unique(id)))) %>%
      left_join(df, ., by = names(df)) %>%
      replace_na(list(id = 0))
    df2
    #      hid mid  tmc  thc  mdc  itc id
    # 1  10001   1   10   10    0   10  1
    # 2  10001   2 1010 1010 1010 1010  2
    # 3  10001   3    0    0    0    0  0
    # 4  10001   4 1020 2030 2020 2020  3
    # 5  10002   1   10   10    0   20  4
    # 6  10002   2   10   20   10   20  5
    # 7  10002   3   10   20   10   20  5
    # 8  10002   4   10   20   10   20  5
    # 9  10002   5   10   30   10   20  6
    # 10 10003   1   10   10    0   10  1
    # 11 10003   2   10   10    0   10  1
    # 12 10003   3   10   10   10   10  7
    # 13 10003   4    0    0    0    0  0
    # 14 10003   5   10   20   10   20  5
    # 15 10003   6   10   30   20   20  8
    # 16 10004   1   10   10    0   10  1
    # 17 10004   2    0    0    0    0  0
    # 18 10004   3 1010 2020 2020 2020  9
    # 19 10004   4   10   30   10   20  6
    # 20 10004   5 1010 4040 1010 2020 10
    
        2
  •  0
  •   mihai valcu    6 年前

    不知道如何解释 id.desired 但以下是基于这两个条件并使用data.table的示例:

     require(data.table)   
     df = data.table(df)   
     df[tmc != 0 & thc != 0 & mdc != 0 & itc != 0, ID := 1:.N, by = .(tmc, thc, mdc, itc)]
     df[is.na(ID), ID := 0]
    
        3
  •  0
  •   Rachit Kinger    6 年前

    (根据你在评论中的澄清修改)
    我试着做两件事:

    1. 为了确保在某些变量为0时id=0,我在mutate函数中使用if-else并指定特定条件。
    2. 得到 id.desired 我使用了dense_rank()函数。

    以下是基于您共享的数据集的代码:

    df %>% 
       mutate(id = if_else(tmc == 0 & thc == 0  & mdc == 0 & itc == 0, 0,
                           as.numeric(interaction(tmc, thc, mdc, itc, lex.order = TRUE)))) %>% 
       mutate(id.desired = dense_rank(id) - 1)
    

    输出如下

        hid   mid  tmc  thc  mdc  itc id   id.desired
    1  10001   1   10   10    0   10 227          1
    2  10001   2 1010 1010 1010 1010 519          7
    3  10001   3    0    0    0    0   0          0
    4  10001   4 1020 2030 2020 2020 775         10
    5  10002   1   10   10    0   20 228          2
    6  10002   2   10   20   10   20 258          4
    7  10002   3   10   20   10   20 258          4
    8  10002   4   10   20   10   20 258          4
    9  10002   5   10   30   10   20 283          5
    10 10003   1   10   10    0   10 227          1
    11 10003   2   10   10    0   10 227          1
    12 10003   3   10   10   10   10 232          3
    13 10003   4    0    0    0    0   0          0
    14 10003   5   10   20   10   20 258          4
    15 10003   6   10   30   20   20 288          6
    16 10004   1   10   10    0   10 227          1
    17 10004   2    0    0    0    0   0          0
    18 10004   3 1010 2020 2020 2020 550          8
    19 10004   4   10   30   10   20 283          5
    20 10004   5 1010 4040 1010 2020 595          9