Je souhaite rassembler toutes les valeurs minimales non nulles des exécutions d'un vecteur séparées par des zéros. Ainsi, les résultats de l'application de mon code au vecteur x ci-dessous doivent être -1, -9 : -1 à partir de -1, 5 et -9 de -4, -9 .
J'exécute le code ci-dessous et j'obtiens le message suivant:
Erreur dans if ((temp [i] == 0) && (temp [i + 1]! = 0)) {: valeur manquante où TRUE / FALSE est nécessaire
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)
temp = c()
minV = c()
for (i in 1:length(x)-1){
temp[i] <- x[i]
if((temp[i] == 0) && (temp[i+1] != 0)){
minV <- c(minV,min(temp))
temp <- c()
}
}
minV
Que puis-je faire pour atteindre mon objectif?
3 Réponses :
L'opérateur : a une priorité inférieure à - . Cela signifie que 1: n - 1 est identique à seq (0, n-1) plutôt que seq (1, n-1) code >.
Je pense que la principale raison pour laquelle ne pas utiliser automatiquement min (x) est qu'il / elle veut traiter chaque section du vecteur séparée par zéro individuellement et obtenir le minimum de chacune.
Il y a donc plusieurs problèmes dans le code comme suit;
1: length (x) -1 ce qui donnera 0 à 8 au lieu de cela, vous voulez le rendre 1: (length (x) - 1) Voici un correctif du code;
# Creating data
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)
# Split string at occurances of zeros
ll <- with(rle(x == 0),{
ifelse(x == 0 & (seq_along(x) != cumsum(lengths)[lengths <= 3 & values]), NA, x)
})
x_split <- split(x, with(rle(is.na(ll)), rep(1:length(lengths), lengths) + ll * 0))
# Get minimum of each vector as list of minimum(s)
lapply(x_split, min)
# $`2`
# [1] -1
#
# $`4`
# [1] -9
# Or get it in form of vector
unlist(lapply(x_split, min), use.names = FALSE)
# [1] -1 -9
# Or use sapply automatically [credit to Ben Bolker]
sapply(x_split, min)
# [1] -1 -9
Cependant, un meilleur moyen est de couper le vecteur chaque fois qu'il rencontre un zéro puis d'obtenir le minimum de chacun des les scissions comme suit;
# Creating data
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)
# Create temp place holders
temp = c()
minV = c()
# Loop on x vector
for (i in 1:(length(x)-1)){
# If x[i] is not zero
if(x[i] != 0){
# Append to temp
temp <- c(temp, x[i])
# If next value is zero then get minimum
if(x[i+1] == 0){
# Get minimum
minV <- c(minV, min(temp))
# Free temp
temp <- c()
}
}
}
minV
# -1 -9
J'aime ta solution. (1) c'est dommage qu'il n'y ait pas de moyen plus compact de faire le fractionnement; (2) pourquoi ne pas utiliser sapply () pour la dernière étape?
Bon point concernant Sapply, je l'ai ajouté à la solution. En ce qui concerne le fractionnement bien, j'ai pensé à une autre façon où je le convertit dans une chaîne puis couper la corde, puis reconvertit-le en vecteur, mais je pense que les deux nécessitent plusieurs étapes. Si vous connaissez une meilleure solution, merci de le partager.
Une version plus simple de la même idée générale: minV <- tapply (x, with (rle (x == 0), rep (seq_along (longueurs), longueurs)), FUN = min); minV [minV! = 0]
Voici une autre alternative si cela vous aide?
x <- c(0, 0, -1, 5, 0, 0, -4, -9, 0)
accumulated.values <- NULL
min.values <- NULL
for (value in x) {
# if we hit a 0
if (value == 0) {
# and we have some values accumulated
if (!is.null(accumulated.values)) {
# calculate the minimum value of the accumulated values
min.values <- c(min.values, min(accumulated.values))
# clear the accumulated values
accumulated.values <- NULL
}
# otherwise ignore
}
else {
# add the value to the accumulated list
accumulated.values <- c(accumulated.values, value)
}
}
min.values
# [1] -1 -9
ressemble à l'un des résultats des contrôles logiques dans
NA. voyez sur quelle valeur deiil s'arrête, puis vérifiez ce que l'instruction if résout pour cette valeur dei. Ensuite, découvrez pourquoi il se résout à NA