1
votes

Fusionner les variables de chaînes entre les tables de données séparées par une virgule et supprimer les doublons dans R

J'ai plusieurs dataframes qui ressemblent à ceci:

  name                    var1
1    A            cat,dog,worm
2    B dog,horse,bird,cat,lion
3    C eagle,fox,chick,giraffe

Je voudrais maintenant fusionner vars1 à 3 pour obtenir une liste concise sans doublons.

Donc, par exemple le bloc de données combiné devrait ressembler à:

df.1 <- data.frame(name = c("A", "B", "C"),
                   var1 = c("cat,dog", "dog,horse,bird", "eagle,fox,chick"))

df.2 <- data.frame(name = c("A", "B", "C"),
                   var2 = c("cat,dog,worm", "dog,horse,bird", "giraffe"))

df.3 <- data.frame(name = c("A", "B", "C"),
                   var3 = c("cat,dog,worm", "dog,horse,bird,cat,lion", NA))
## merged 
all <- df.1 %>% 
  left_join(df.2) %>% 
  left_join(df.3)

> all
  name            var1           var2                    var3
1    A         cat,dog   cat,dog,worm            cat,dog,worm
2    B  dog,horse,bird dog,horse,bird dog,horse,bird,cat,lion
3    C eagle,fox,chick        giraffe                    <NA>

paste permettra de fusionner des chaînes séparées par des virgules, mais je ne sais pas comment supprimer les doublons?

Je voudrais faire cela en utilisant tidyverse et pas un autre paquet.


3 commentaires

Cela peut aider: stackoverflow.com/questions/35286596/... Collez simplement toutes les valeurs des colonnes en premier: stackoverflow.com/questions/14568662/...


est-il possible de faire ce découpage unique dans dplyr?


Il n'y a rien de spécial à déplyr pour le fractionnement. C'est purement une opération de chaîne. Vos données ne sont pas "rangées", donc ce n'est pas génial pour les verbes dplyr. Le package stringr est plus utile pour le fractionnement. Ou vous pouvez utiliser la fonction tidyr :: separ_rows () pour rendre vos données plus ordonnées. Utilisez les valeurs non pas comme une chaîne séparée par des virgules, mais comme des valeurs de cellule appropriées.


4 Réponses :


0
votes

Utilisation de baseR ,

  name            var1           var2                    var3                     VAR
1    A         cat,dog   cat,dog,worm            cat,dog,worm            cat,dog,worm
2    B  dog,horse,bird dog,horse,bird dog,horse,bird,cat,lion dog,horse,bird,cat,lion
3    C eagle,fox,chick        giraffe                    <NA> eagle,fox,chick,giraffe

gives ,

all$VAR <- sapply(seq(nrow(all)),function(x) {

            k <- paste(unlist(all[x,2:4][,!is.na(all[x,2:4])]),collapse=",")
            paste(unique(unlist(strsplit(k,","))),collapse=",") })


0 commentaires

0
votes

C'est une solution entièrement tidyverse , bien qu'un peu longue en code. Il peut sûrement être optimisé, mais il répond à votre question.

Pour une meilleure explication de toutes les étapes, je vous suggère de les exécuter une par une pour comprendre les opérations effectuées et comment le jeu de données change après chaque étape. P >

library(tidyverse)

all %>% 
  pivot_longer(starts_with("var"), names_to = "vars") %>% 
  mutate(value = str_split(value, ",")) %>% 
  unnest(value) %>%
  filter(!is.na(value)) %>% 
  group_by(name) %>% 
  distinct(value) %>% 
  mutate(var = paste(value, collapse = ",")) %>% 
  select(-value) %>% 
  ungroup() %>% 
  distinct()

# A tibble: 3 x 2
#   name  var                    
#   <chr> <chr>                  
# 1 A     cat,dog,worm           
# 2 B     dog,horse,bird,cat,lion
# 3 C     eagle,fox,chick,giraffe


0 commentaires

1
votes

Vous pouvez obtenir les données au format long, obtenir des valeurs dans différentes lignes, pour chaque nom créer une valeur unique non-NA séparée par des virgules.

all$var4 <- apply(all[-1], 1, function(x) 
                  toString(na.omit(unique(unlist(strsplit(x, ','))))))

En base R, nous pouvons utiliser apply ligne par ligne:

library(dplyr)
library(tidyr)

all %>%
  pivot_longer(cols = var1:var3, names_to = 'col') %>%
  separate_rows(value) %>%
  group_by(name) %>%
  summarise(var1 = toString(na.omit(unique(value))))

# name  var1                       
#  <chr> <chr>                      
#1 A     cat, dog, worm             
#2 B     dog, horse, bird, cat, lion
#3 C     eagle, fox, chick, giraffe 


0 commentaires

0
votes

Voici une solution base R :

Première étape: collez les lignes ensemble, strsplit , réduisez-les à uniques valeurs, combinez toString , et supprimez NA:

new
  name                        var1
1    A              cat, dog, worm
2    B dog, horse, bird, cat, lion
3    C  eagle, fox, chick, giraffe

Deuxième étape: column-bind tous [1] avec var1

new <- cbind(all[1], var1)

Résultat:

var1 <- gsub(", NA", "", unlist(as.character(lapply(sapply(strsplit(apply(all[2:4], 1, paste0, collapse = " "), " |,"), unique), toString))))

p >


0 commentaires