3
votes

Coller des valeurs de différentes colonnes et de différentes lignes dans un nouveau df dans R

J'ai le df suivant ci-dessous:

1 yaaA recF
2 yaaD
3 dck
4 dnaX yaaK recR
5 xpaC
6 yaaO
7 yaaQ yaaR holB yaaT
8 yabB yazA

J'essaie de trouver un moyen de coller ensemble les valeurs du nom et du nom..2 où nom..2 correspond au nom dans le suivant row et mettez-le dans un nouveau df qui devrait ressembler à ceci:

 name name..2 IGD
1 yaaA    recF  16
2 recF    yaaB  18
3 yaaD    yaaE  22
4  dck     dgk  -3
5 dnaX    yaaK  24
6 yaaK    recR  15
7  recR    yaaL  18
8  xpaC    yaaN  19
9  yaaO     tmk  -3
10 yaaQ    yaaR  13
11 yaaR    holB  12
12 holB    yaaT   3
13 yaaT    yabA  15
14 yabB    yazA -13
15 yazA    yabC -25

Y a-t-il une fonction que je peux utiliser pour cela? J'ai essayé de rechercher SO, mais je n'ai pas encore trouvé de solution à ce problème. Merci d'avance pour l'aide.


2 commentaires

Les valeurs de la colonne IGD peuvent donc être ignorées?


Oui, IGD peut être ignoré, ils sont le résultat de la façon dont j'ai assemblé le df


4 Réponses :


2
votes

Dans Base R, nous utilisons tail head et cumsum créons la clé de groupe, puis en utilisant aggregate < pré> XXX


2 commentaires

La logique est correcte, mais le lag dans ce cas d'utilisation provient de dplyr et ne le fait pas en base R (pour être précis, lag est dans le package "stats" inclus par défaut, où il est utilisé pour les séries chronologiques). Vous pouvez le remplacer par cumsum (c (TRUE, tail (df $ name, -1)! = Head (df $ name2, -1)))


@thelatemail aha merci d'avoir mentionné cela, mis à jour



2
votes

Voici une autre option qui consiste à identifier les clusters dans un igraph

df <- read.table(text =
    " name name..2 IGD
1 yaaA    recF  16
2 recF    yaaB  18
3 yaaD    yaaE  22
4  dck     dgk  -3
5 dnaX    yaaK  24
6 yaaK    recR  15
7  recR    yaaL  18
8  xpaC    yaaN  19
9  yaaO     tmk  -3
10 yaaQ    yaaR  13
11 yaaR    holB  12
12 holB    yaaT   3
13 yaaT    yabA  15
14 yabB    yazA -13
15 yazA    yabC -25", header = T)

L'idée est de construire un igraph depuis df [c ("name", "name..2")] puis pour identifier les clusters de nœuds connectés. Les clusters sont alors les groupes, et tout ce que nous avons à faire est de supprimer le dernier élément (nœud).


Exemple de données

library(igraph)
library(tidyverse)
df %>%
    select(-IGD) %>%
    graph_from_data_frame() %>%
    clusters() %>%
    magrittr::extract2(1) %>%
    split(., .) %>%
    map_dfr(~tibble(x = toString(names(.x)[-length(.x)])))
## A tibble: 8 x 1
#  x
#  <chr>
#1 yaaA, recF
#2 yaaD
#3 dck
#4 dnaX, yaaK, recR
#5 xpaC
#6 yaaO
#7 yaaQ, yaaR, holB, yaaT
#8 yabB, yazA


0 commentaires

3
votes

La logique est similaire à @ Wen-Ben ici, une façon dplyr de faire cela

library(dplyr)

df %>%
  group_by(group = cumsum(name != lag(name2, default = TRUE))) %>%
  summarise(name = toString(name))

#  group name                  
#  <int> <chr>                 
#1     1 yaaA, recF            
#2     2 yaaD                  
#3     3 dck                   
#4     4 dnaX, yaaK, recR      
#5     5 xpaC                  
#6     6 yaaO                  
#7     7 yaaQ, yaaR, holB, yaaT
#8     8 yabB, yazA     

L'idée principale est de créer une variable de regroupement qui incrémente chaque heure nom! = nom2 .


1 commentaires

Merci pour l'aide, j'ai choisi cette solution car j'avais déjà dplyr chargé dans mon environnement, mais les trois solutions affichées fonctionnaient sur mes ensembles de données. La partie principale avec laquelle je me débattais était de savoir comment incrémenter ligne par ligne. Je n'ai jamais eu à utiliser ce genre de logique auparavant.



0
votes

Nous pouvons le faire dans data.table ainsi que dans

df <- structure(list(name = c("yaaA", "recF", "yaaD", "dck", "dnaX", 
"yaaK", "recR", "xpaC", "yaaO", "yaaQ", "yaaR", "holB", "yaaT", 
"yabB", "yazA"), name2 = c("recF", "yaaB", "yaaE", "dgk", "yaaK", 
"recR", "yaaL", "yaaN", "tmk", "yaaR", "holB", "yaaT", "yabA", 
 "yazA", "yabC"), IGD = c(16L, 18L, 22L, -3L, 24L, 15L, 18L, 19L, 
 -3L, 13L, 12L, 3L, 15L, -13L, -25L)), class = "data.frame",
  row.names = c("1", 
  "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
 "14", "15"))

data

library(data.table)
setDT(df)[, .(name = toString(name)), 
      .(group = cumsum(name != shift(name2, fill = TRUE)))]
#   group                   name
#1:     1             yaaA, recF
#2:     2                   yaaD
#3:     3                    dck
#4:     4       dnaX, yaaK, recR
#5:     5                   xpaC
#6:     6                   yaaO
#7:     7 yaaQ, yaaR, holB, yaaT
#8:     8             yabB, yazA


0 commentaires