1
votes

comparer plusieurs valeurs avec plusieurs valeurs dans R Dataframe

J'ai un bloc de données avec 2 colonnes, "time et" a ".

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5), comp = c(F, F, F, F, T, F, F, F, F)

Comment est-il possible de comparer si les valeurs ont changé au fil du temps? J'ai besoin d'une nouvelle colonne" comp "dans le bloc de données qui montre si la troisième valeur de la colonne" c "est toujours la même que les deux dernières valeurs et les deux valeurs précédentes dans la même colonne. Le résultat pourrait donc ressembler à ceci:

df <- data.frame(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9), a = c(3, 8, 2, 2, 2, 2, 2, 4, 5))

En fin de compte, je dois comparer une colonne avec environ 3 millions d'observations.


0 commentaires

3 Réponses :


3
votes

Utilisation du tidyverse:

library(tidyverse)

df %>% 
  arrange(time) %>% 
  mutate(comp = a == lag(a) & a == lag(a, 2) & a == lead(a) & a == lead(a, 2))

#   time a  comp
# 1    1 3 FALSE
# 2    2 8 FALSE
# 3    3 2 FALSE
# 4    4 2 FALSE
# 5    5 2  TRUE
# 6    6 2 FALSE
# 7    7 2 FALSE
# 8    8 4 FALSE
# 9    9 5 FALSE


2 commentaires

solution agréable et facile :) et si je voudrais comparer des valeurs spécifiques. Par exemple, le résultat n'est True que s'il y a deux (comme dans mon exemple df) qui n'ont pas changé ou (comme condition) six?


Vous pouvez simplement continuer à ajouter des conditions à droite de l'instruction comp = ... , telles que & a == 2 .



1
votes

Si je comprends bien, vous recherchez des valeurs identiques à leurs 2 valeurs adjacentes de chaque côté, et dans ce cas, vous êtes heureux d'ignorer les valeurs adjacentes «manquantes» pour les 2 premières et 2 dernières valeurs.

En utilisant la base R:

[1] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE

Sortie:

sameasadj=function(v,n=2,include_ends=T) {
    if(include_ends){vv=c(rep(head(v,1),n),v,rep(tail(v,1),n))} 
    else {vv=c(rep(NA,n),v,rep(NA,n))}
    sapply(seq_along(v),function(i) diff(range(vv[i:(i+2*n)]))==0)
}

df$comp = sameasadj(df$a)
df$comp

Explication:

sameasadj = function (v, n = 2, include_ends = T) = définir la fonction sameasadj pour tester si chaque valeur est la même que ses voisins adjacents de chaque côté. Nous pouvons donner la possibilité de choisir le nombre n de voisins adjacents (dans votre cas 2), et d'inclure ou non les extrémités (ou de retourner 'NA' pour ceux-ci, car ils manquent de voisins d'un côté).

if (include_ends) {vv = c (rep (head (v, 1), n), v, rep (tail (v, 1), n))} = si nous voulons inclure les extrémités, alors nous ajoutons simplement les voisins 'manquants' pour qu'ils correspondent

else {vv = c (rep (NA, n), v, rep (NA , n))} = sinon nous ajoutons des valeurs 'NA'

sapply (seq_along (v), function (i) = aller le long de chaque position i dans le vector ...

diff (range (vv [i: (i + 2 * n)])) == 0) = ... et vérifiez si les éléments de i à i + 2 * n sont tous identiques ( diff (range (x)) == 0 retournera TRUE si tous les éléments de x sont identiques) p>

Mettre tout cela dans une fonction vous permet de changer d'avis plus tard sur le nombre de voisins adjacents, ou sur ce qu'il faut faire avec les extrémités ...


0 commentaires

2
votes

Une solution similaire à @Bas en utilisant data.table

library(data.table)
setDT(df)[, comp := a == shift(a) & a == shift(a, 2) & 
                  a == shift(a, type = 'lead') & a == shift(a, 2, type = 'lead')]

#   time a  comp
#1:    1 3 FALSE
#2:    2 8 FALSE
#3:    3 2 FALSE
#4:    4 2 FALSE
#5:    5 2  TRUE
#6:    6 2 FALSE
#7:    7 2 FALSE
#8:    8 4 FALSE
#9:    9 5 FALSE


2 commentaires

merci pour votre solution data.table! Et si je veux vérifier par exemple les 20 valeurs suivantes? Il doit y avoir une meilleure solution que d'écrire shift (a, 1) , shift (a, 2) etc .... parce que si j'essaye setDT (df ) [ comp: = a == shift (a, type = "lag", n = c (1: 2)) & a == shift (a, type = "lead", n = c (1: 2) )] J'obtiens une erreur: l'objet 'list' ne peut pas être contraint de taper 'double'


Vous pouvez utiliser des opérations de roulement. Découvrez la fonction ? Rolapply de zoo . Vous pouvez poser une nouvelle question si vous rencontrez des difficultés pour l'implémenter pour vos données.