joindre les informations de deux dataframes R

Oct 26 2020

J'aimerais joindre deux dataframes avec R ici le premier

   resno resid elety eleno
    1     ILE     C     3
    1     ILE     O     4
    2     VAL     C    11
    2     VAL     O    12
    3     GLY     C    18
    3     GLY     O    19

le deuxième

   C.O     dist
  12-18   3.112819
  27-37   2.982788
  51-63   3.185184
  52-62   2.771583
  63-69   3.157737
  70-80   2.956738

alors expliquons ce dont j'ai besoin. En regardant la seconde trame de données, j'ai une distance ("dist") entre les points 12 à 18, correspondant à "eleno" dans la première trame de données. pour ces 2 points j'ai aussi "resno" c'est ce qui m'intéresse, parce que j'aimerais obtenir quelque chose comme ça

       resno resid elety eleno rescoup   dist
        1     ILE     C     3     -       -
        1     ILE     O     4     -       -
        2     VAL     C    11     -       -
        2     VAL     O    12    2-3   3.112819
        3     GLY     C    18    2-3   3.112819
        3     GLY     O    19     -       -

Comment puis-je faire? est-ce possible avec R?

Merci!

Réponses

1 RonakShah Oct 26 2020 at 11:29

Vous pouvez d'abord créer une longue trame de données à partir de df2laquelle chaque numéro C.Oest une ligne unique.

library(dplyr)
library(tidyr)

df3 <- df2 %>%
  separate(C.O, c('col1', 'col2'), sep = '-', convert = TRUE) %>%
  mutate(eleno = purrr::map2(col1, col2, seq), .before = 1, 
         row = row_number()) %>%
  select(-col1, -col2) %>%
  unnest(eleno)

df3
# A tibble: 60 x 3
#   eleno   row  dist
#   <int> <int> <dbl>
# 1    12     1  3.11
# 2    13     1  3.11
# 3    14     1  3.11
# 4    15     1  3.11
# 5    16     1  3.11
# 6    17     1  3.11
# 7    18     1  3.11
# 8    27     2  2.98
# 9    28     2  2.98
#10    29     2  2.98
# … with 50 more rows

Joignez - vous à cette trame de données avec df1et les paste resnovaleurs pour créer rescoup.

df1 %>%
  left_join(df3, by = 'eleno') %>%
  group_by(row) %>%
  mutate(rescoup = paste(resno, collapse = '-'), 
         rescoup = replace(rescoup, is.na(dist), NA)) %>%
  ungroup() %>%
  select(-row)

#  resno resid elety eleno  dist rescoup
#  <int> <chr> <chr> <int> <dbl> <chr>  
#1     1 ILE   C         3 NA    NA     
#2     1 ILE   O         4 NA    NA     
#3     2 VAL   C        11 NA    NA     
#4     2 VAL   O        12  3.11 2-3    
#5     3 GLY   C        18  3.11 2-3    
#6     3 GLY   O        19 NA    NA     
zx8754 Oct 26 2020 at 11:45

À l'aide de data.table , fractionner puis fusionner:

library(data.table)

merge(d1,
      d2[, lapply(.SD, function(x) unlist(tstrsplit(x, "-", fixed = TRUE,
                                                    type.convert = TRUE)))],
      by.x = "eleno", by.y = "C.O", all.x = TRUE)

#    eleno resno resid elety     dist
# 1:     3     1   ILE     C       NA
# 2:     4     1   ILE     O       NA
# 3:    11     2   VAL     C       NA
# 4:    12     2   VAL     O 3.112819
# 5:    18     3   GLY     C 3.112819
# 6:    19     3   GLY     O       NA
Exemple de données:
d1 <-   fread("resno resid elety eleno
1     ILE     C     3
1     ILE     O     4
2     VAL     C    11
2     VAL     O    12
3     GLY     C    18
3     GLY     O    19")
d2 <- fread("C.O     dist
12-18   3.112819
27-37   2.982788
51-63   3.185184
52-62   2.771583
63-69   3.157737
70-80   2.956738")