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.
4 Réponses :
Dans Base R, nous utilisons tail
head
et cumsum
créons la clé de groupe, puis en utilisant aggregate
< pré> XXX
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
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).
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
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
.
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.
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"))
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
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