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))
3 Réponses :
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"
merci beaucoup pour cela. J'ai une nouvelle question de suivi sur ce stackoverflow.com/questions/54291153/...
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.
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"