Lorsque je dois filtrer un nom data.fr, c’est-à-dire extraire des lignes qui répondent à certaines conditions, je préfère utiliser la fonction subset
:
subset(airquality, Month == 8 & Temp > 90)
Plutôt que la fonction [
:
airquality[airquality$Month == 8 & airquality$Temp > 90, ]
Il y a deux raisons principales à ma préférence:
Je trouve que le code se lit mieux, de gauche à droite. Même les personnes qui ne connaissent rien à R pourraient dire ce que la déclaration subset
ci-dessus fait.
Étant donné que les colonnes peuvent être appelées variables dans l'expression select
, je peux enregistrer quelques frappes au clavier. Dans l'exemple ci-dessus, je n'avais qu'à taper airquality
une fois avec subset
, mais trois fois avec [
.
Donc, je vivais heureux, en utilisant subset
partout car il est plus court et lit mieux, même en préconisant sa beauté à mes collègues codeurs R. Mais hier, mon monde s'est brisé. En lisant la documentation subset
, je remarque cette section:
Attention
C'est une fonction pratique destinée à être utilisée de manière interactive. Pour la programmation, il est préférable d'utiliser les fonctions de sous-ensemble standard telles que [ et en particulier l'évaluation non standard d'un sous-ensemble d'arguments peut avoir des conséquences imprévues.
Quelqu'un pourrait-il aider à clarifier ce que les auteurs veulent dire?
Premièrement, qu’entendent-ils par "pour une utilisation interactive"? Je sais ce qu'est une session interactive, par opposition à un script exécuté en mode BATCH, mais je ne vois pas quelle différence cela devrait faire.
Ensuite, pourriez-vous expliquer "l'évaluation non standard du sous-ensemble d'arguments" et pourquoi c'est dangereux, donnez peut-être un exemple?
@James a bien répondu à cette question, soulignant l'excellente explication de Hadley Wickham sur les dangers de subset
(et fonctionne de la même manière) [ici] . Allez le lire!
La lecture étant assez longue, il peut être utile de noter ici l'exemple cité par Hadley qui aborde le plus directement la question de "qu'est-ce qui peut mal tourner?":
Hadley suggère l'exemple suivant: supposons que nous voulions créer un sous-ensemble, puis réorganiser une trame de données à l'aide des fonctions suivantes:
scramble <- function(x) x[sample(nrow(x)), ]
subscramble <- function(x, condition) {
scramble(subset(x, condition))
}
subscramble(mtcars, cyl == 4)
Cela renvoie l'erreur:
Erreur dans eval (expr, envir, enclos): objet 'cyl' non trouvé
parce que R ne "sait" plus où trouver l'objet appelé "cyl". Il signale également les choses vraiment bizarres qui peuvent se produire si, par hasard, il existe un objet appelé "cyl" dans l'environnement mondial:
cyl <- 4
subscramble(mtcars, cyl == 4)
cyl <- sample(10, 100, rep = T)
subscramble(mtcars, cyl == 4)
(Exécutez-les et voyez par vous-même, c'est assez fou.)
Aussi [
est plus rapide:
require(microbenchmark)
microbenchmark(subset(airquality, Month == 8 & Temp > 90),airquality[airquality$Month == 8 & airquality$Temp > 90,])
Unit: microseconds
expr min lq median uq max neval
subset(airquality, Month == 8 & Temp > 90) 301.994 312.1565 317.3600 349.4170 500.903 100
airquality[airquality$Month == 8 & airquality$Temp > 90, ] 234.807 239.3125 244.2715 271.7885 340.058 100