Disons que j'ai une table de données et que je veux sélectionner toutes les lignes où la variable x a une valeur de b. C'est facile
library(data.table)
DT <- data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9)
setkey(DT,x) # set a 1-column key
DT["b"]
Soit dit en passant, il semble que l'on doit définir une clé, si la clé n'est pas définie sur x, cela ne fonctionne pas. Au fait, que se passerait-il si je définissais deux colonnes comme clés?
Quoi qu'il en soit, en avançant, disons que je veux sélectionner toutes les lignes où la variable x était a ou b
DT["b"|"a"]
ne marche pas
Mais les œuvres suivantes
DT[x=="a"|x=="b"]
Mais cela utilise un balayage vectoriel sur les trames de données. Il n'utilise pas la recherche binaire. Je suppose que pour les petits ensembles de données, cela n'aura pas d'importance.
Est-ce ce que je dois faire ou suis-je ignorant de la syntaxe data.table?
Et encore une chose. Existe-t-il des exemples de procédures de sélection (ou sous-ensemble) de variables booléennes plus complexes avec data.table?
Je sais que je pourrais toujours revenir à l'utilisation de la fonction subset () car un data.table se comportera comme un data.frame s'il le faut.
Voici une façon qui ne m'est venue à l'esprit qu'après avoir posé la question et ça marche mais je ne sais pas comment ça se passe dans les benchmarks. Je ne suis pas actuellement sur un ordinateur avec un R. installé. Je suppose que je devrais utiliser une instance cloud. Quoi qu'il en soit, j'aime la syntaxe
DT[c("a","b")]
En utilisant le %in%
L'opérateur semble donner un facteur de 2 bosse de performance. Considérer:
library(data.table)
library(rbenchmark)
DT <- data.table(x=sample(letters, 1e6, TRUE), y=rnorm(1e6), v=runif(1e6))
setkey(DT,x) # set a 1-column key
DT["b"]
f1 <- function() DT[x %in% letters[1:2]]
f2 <- function() DT[x=="a"| x == "b"]
> benchmark(f1(),f2())
test replications elapsed relative user.self sys.self user.child sys.child
1 f1() 100 8.40 1.000000 7.58 0.81 NA NA
2 f2() 100 17.11 2.036905 15.54 1.56 NA NA
> all.equal(f1(), f2())
[1] TRUE
EDIT: Ajout de l'option de Farrel
Notez que ceci est sur un ordinateur différent, mais les bosses relatives sont les mêmes.
f3 <- function() DT[c("a", "b")]
test replications elapsed relative user.self sys.self user.child sys.child
1 f1() 100 11.281 7.121843 9.745 1.323 0 0
2 f2() 100 23.106 14.587121 20.824 2.224 0 0
3 f3() 100 1.584 1.000000 1.042 0.541 0 0