4
votes

Renvoie les lignes où les valeurs consécutives répondent au critère

J'ai le dataframe suivant df . Je voudrais renvoyer un résultat vectoriel qui indique quelles lignes répondent au critère suivant: au moins 2 valeurs consécutives dans cette ligne sont inférieures à -1,7.

result <- c(1977,1979,1980,1982,1983,1985)

Le le résultat serait un vecteur:

set.seed(123)

df <- data.frame(V1=rnorm(10,-1.5,.5),
                 V2=rnorm(10,-1.5,.5),
                 V3=rnorm(10,-1.5,.5),
                 V4=rnorm(10,-1.5,.5),
                 V5=rnorm(10,-1.5,.5),
                 V6=rnorm(10,-1.5,.5),
                 V7=rnorm(10,-1.5,.5),
                 V8=rnorm(10,-1.5,.5),
                 V9=rnorm(10,-1.5,.5),
                 V10=rnorm(10,-1.5,.5))
rownames(df) <- c(seq(1976,1985,1))


0 commentaires

3 Réponses :


3
votes

Une option consiste à parcourir les lignes avec apply , créer une condition logique avec rle , vérifier s'il y a des éléments TRUE qui avoir longueurs plus de 1, extraire les noms

names(which(rowSums(Reduce(`&`, list(df[-ncol(df)] < -1.7, df[-1] < -1.7))) > 0))
#[1] "1977" "1979" "1980" "1982" "1983" "1985"

Ou une meilleure approche est de le vectoriser en plaçant deux matrices logiques (c.-à-d. supprimer la première colonne de l'ensemble de données, vérifier si elle est inférieure à -1,7, supprimer de la même manière la dernière colonne et faire de même), réduire en une seule matrice code logique > en vérifiant si les éléments correspondants sont TRUE , récupérez les rowSums , si la valeur est supérieure à 0, nous extrayons les noms de lignes

names(which(apply(df, 1, function(x) with(rle(x < - 1.7), any(lengths[values] > 1)))))
#[1] "1977" "1979" "1980" "1982" "1983" "1985"


1 commentaires

merci beaucoup pour cela. J'ai une nouvelle question de suivi sur ce stackoverflow.com/questions/54291153/...



3
votes

Une option amusante utilisant qui avec arr.ind = TRUE

temp <- which(df < -1.7, arr.ind = TRUE)
rownames(df)[aggregate(col~row, temp, function(x) any(diff(x) == 1))[, 2]]

#[1] "1977" "1979" "1980" "1982" "1983" "1985"

Nous obtenons d'abord toutes les positions de ligne et de colonne où la valeur est moins de -1,7. En utilisant aggregate nous regroupons col pour chaque ligne et vérifions s'il y a au moins une valeur consécutive dans une ligne et pour les valeurs qui renvoient TRUE sous-ensemble ses noms.


0 commentaires

2
votes

Une solution qui utilise la somme retardée pour obtenir la somme de chaque paire de nombres dans un vecteur. Si la somme retardée est de 2, cela signifie qu'au moins 2 valeurs consécutives de cette ligne remplissent la condition.

rownames(df)[apply(df < -1.7, 1, function(x) any(x[-nrow(df)] + x[-1] == 2))]

# [1] "1977" "1979" "1980" "1982" "1983" "1985"


0 commentaires