web-dev-qa-db-fra.com

sous-ensemble dans data.table

J'essaye de sous-ensemble un data.table (du paquet data.table ) dans R (pas un data.frame). J'ai une année à 4 chiffres comme clé. Je voudrais sous-ensemble en prenant une série d'années. Par exemple, je veux extraire tous les enregistrements qui datent de 1999, 2000, 2001.

J'ai essayé de transmettre ma syntaxe de recherche binaire DT[J(year)] comme suit:

1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001

mais aucun de ceux-ci ne semble fonctionner. Quelqu'un sait-il comment créer un sous-ensemble où les années que vous souhaitez sélectionner ne sont pas seulement 1 mais plusieurs années?

17
exl

Ce qui fonctionne pour data.frames fonctionne pour data.tables.

subset(DT, year %in% 1999:2001)
19
Richie Cotton

La question n'est pas claire et ne fournit pas suffisamment de données pour travailler avec MAIS elle est utile, donc si quelqu'un peut la modifier avec les données que je fournis ci-dessous, l'une est la bienvenue. Le titre du poste pourrait également être complété: Matthew Dowle répond souvent à la question du sous-ensemble sur deux vecteurs, mais moins fréquemment de la question du sous-ensemble selon une déclaration dans un énoncé sur un vecteur. Je cherche depuis longtemps une réponse, jusqu'à ce que j'en trouve un pour les vecteurs de caractères ici .

Prenons ces données:

library(data.table)
n <- 100
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)

La requête de style data.table correspondant à X[X$a %in% c(10,20),] est quelque peu surprenante:

setkey(X,a)
X[.(c(10,20))]
X[.(10,20)] # works for characters but not for integers
            # instead, treats 10 as the filter
            # and 20 as a new variable

# for comparison :
X[X$a %in% c(10,20),]

Maintenant, quel est le meilleur? Si votre clé est déjà définie, data.table, évidemment. Sinon, il se peut que ce ne soit pas le cas, comme le prouvent les mesures de temps suivantes (sur mon ordinateur 1,75 Go RAM):

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(X[X$a %in% c(10,20),])
# utilisateur     système      écoulé (yes, I'm French) 
#        1.92        0.06        1.99
system.time(setkey(X,a))
# utilisateur     système      écoulé 
#       34.91        0.05       35.23 
system.time(X[J(c(10,20))])
# utilisateur     système      écoulé 
#        0.15        0.08        0.23

Mais peut-être que Matthew a de meilleures solutions ...


[Matthew] Vous avez découvert que le type de tri numeric (a.k.a. double) est beaucoup plus lent que integer. Pendant de nombreuses années, nous n'avons pas autorisé double dans les clés par crainte que les utilisateurs ne tombent dans ce piège et ne signalent des horaires horribles comme celui-ci. Nous avons autorisé double dans les clés avec une certaine inquiétude car le tri rapide n'est pas encore implémenté pour double. Un tri rapide sur integer et character est assez bon car ceux-ci sont effectués à l'aide d'un tri de comptage. J'espère que nous arriverons à un tri rapide numeric un jour! (Maintenant implémenté - voir ci-dessous).

Timings on data.table pre-1.9.0

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#   user  system elapsed 
# 13.898   0.138  14.216 

X <- data.table(a=sample(as.integer(c(10,20,25,30,40)),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
#   user  system elapsed 
#  0.381   0.019   0.408 

N'oubliez pas que 2 Est de type numeric dans R par défaut. 2L Est integer. Bien que data.table Accepte numeric, il préfère toujours beaucoup integer.


Le tri rapide de radix pour les numériques est implémenté depuis la v1.9.0.

À partir de la v1.9.0

n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#    user  system elapsed 
#   0.832   0.026   0.871 
15
Arthur

Comme ci-dessus, mais plus de données.table esque:

DT[year %in% c(1999, 2000, 2001)]

8
Yike Lu

Cela fonctionnera:

sample_DT = data.table(year = rep(1990:2010, length.out = 1000), 
                       random_number = rnorm(1000), key = "year")
year_subset = sample_DT[J(c(1990, 1995, 1997))]

De même, vous pouvez saisir une table de données déjà existante avec setkey (existing_DT, year), puis utiliser la syntaxe J() comme indiqué ci-dessus.

Je pense que le problème peut être que vous n'avez pas saisi les données en premier.

1
Taylor White