简体   繁体   中英

Assign progressive ID based on two criteria

I have two columns about the IDs of participants in my study. The column ID contains progressive order of numbers as the subjects were all distinct people. The second column new_ID contains the information about which IDs correspond to the same person. Unfortunately they are not in the progressive order.

ID <- c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6)
new_ID <- c(8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10)

data.frame(ID, new_ID)

#   ID  new_ID
#1   1       8
#2   1       8
#3   1       8
#4   1       8
#5   2      10
#6   2      10
#7   2      10
#8   2      10
#9   2      10
#10  2      10
#11  3       8
#12  3       8
#13  3       8
#14  3       8
#15  3       8
#16  4       4
#17  4       4
#18  4       4
#19  4       4
#20  4       4
#21  4       4
#22  5       5
#23  5       5
#24  5       5
#25  5       5
#26  6      10
#27  6      10
#28  6      10
#29  6      10
#30  6      10
#31  6      10
#32  6      10

I reported below what I would like to achieve, ie assigning the new ID ( final_ID ) based on the information in the two first columns. Any helps will be appreciated (best if using dplyr )!


#   ID new_ID ID_final
#1   1      8        1
#2   1      8        1
#3   1      8        1
#4   1      8        1
#5   2     10        2
#6   2     10        2
#7   2     10        2
#8   2     10        2
#9   2     10        2
#10  2     10        2
#11  3      8        1
#12  3      8        1
#13  3      8        1
#14  3      8        1
#15  3      8        1
#16  4      4        4
#17  4      4        4
#18  4      4        4
#19  4      4        4
#20  4      4        4
#21  4      4        4
#22  5      5        5
#23  5      5        5
#24  5      5        5
#25  5      5        5
#26  6     10        2
#27  6     10        2
#28  6     10        2
#29  6     10        2
#30  6     10        2
#31  6     10        2
#32  6     10        2

Here's a data.table solution as well.

EDIT: added a dplyr solution too at the request of the OP.

library(data.table)
ID <- c(1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6)
new_ID <- c(8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10)

d <- data.table(ID, new_ID)
d[, ID_final := min(.SD[,ID]), new_ID]
d
#>     ID new_ID ID_final
#>  1:  1      8        1
#>  2:  1      8        1
#>  3:  1      8        1
#>  4:  1      8        1
#>  5:  2     10        2
#>  6:  2     10        2
#>  7:  2     10        2
#>  8:  2     10        2
#>  9:  2     10        2
#> 10:  2     10        2
#> 11:  3      8        1
#> 12:  3      8        1
#> 13:  3      8        1
#> 14:  3      8        1
#> 15:  3      8        1
#> 16:  4      4        4
#> 17:  4      4        4
#> 18:  4      4        4
#> 19:  4      4        4
#> 20:  4      4        4
#> 21:  4      4        4
#> 22:  5      5        5
#> 23:  5      5        5
#> 24:  5      5        5
#> 25:  5      5        5
#> 26:  6     10        2
#> 27:  6     10        2
#> 28:  6     10        2
#> 29:  6     10        2
#> 30:  6     10        2
#> 31:  6     10        2
#> 32:  6     10        2
#>     ID new_ID ID_final

library(dplyr)
df <- data.frame(ID, new_ID)
df <- df %>% group_by(new_ID)  %>%
  mutate(ID_final = min(ID))
df
#> # A tibble: 32 x 3
#> # Groups:   new_ID [4]
#>       ID new_ID ID_final
#>    <dbl>  <dbl>    <dbl>
#>  1     1      8        1
#>  2     1      8        1
#>  3     1      8        1
#>  4     1      8        1
#>  5     2     10        2
#>  6     2     10        2
#>  7     2     10        2
#>  8     2     10        2
#>  9     2     10        2
#> 10     2     10        2
#> # ... with 22 more rows

Created on 2019-09-30 by the reprex package (v0.3.0)

What you want to do is find the correct ID for each new_ID, and then join to that mapping.

final_id_map <- df %>% group_by(new_ID) %>% summarise(ID_final=min(ID))
> final_id_map
# A tibble: 4 x 2
  new_ID ID_final
   <dbl>    <dbl>
1      4        4
2      5        5
3      8        1
4     10        2

Then you can just do a

df %>% join(final_id_map)

to produce the desired output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM