web-dev-qa-db-fra.com

Que pouvez-vous faire avec un data.frame que vous ne pouvez pas avec un data.table?

Je viens de commencer à utiliser R et je suis tombé sur data.table. Je l'ai trouvé génial.

Une question très naïve: puis-je ignorer data.frame pour utiliser data.table pour éviter la confusion de syntaxe entre deux packages?

69
AdamNYC

De la FAQ data.table

FAQ 1.8 OK, je commence à voir de quoi traite data.table, mais pourquoi n'avez-vous pas amélioré data.frame dans R? Pourquoi faut-il que ce soit un nouveau package?

Comme FAQ 1.1 met en évidence, j dans [.data.table Est fondamentalement différent de j dans [.data.frame. Même quelque chose d'aussi simple que DF[,1] Briserait le code existant dans de nombreux packages et code utilisateur. De par sa conception, nous souhaitons qu'il fonctionne de cette manière pour que la syntaxe soit plus compliquée. Il existe également d'autres différences (voir FAQ 2.17).

De plus, data.table Hérite de data.frame. C'est aussi un data.frame. Un data.table Peut être transmis à n'importe quel package qui accepte uniquement data.frame Et ce package peut utiliser la syntaxe [.data.frame Sur le data.table.

Nous avons également proposé des améliorations à R dans la mesure du possible. L'une d'elles a été acceptée comme nouvelle fonctionnalité dans R 2.12.0:

unique() et match() sont désormais plus rapides sur les vecteurs de caractères où tous les éléments sont dans le cache global CHARSXP et ont un codage non marqué (ASCII). Merci à Matthew Dowle d'avoir suggéré des améliorations à la façon dont le code de hachage est généré dans unique. C.

Une deuxième proposition consistait à utiliser memcpy dans duplicate.c, Ce qui est beaucoup plus rapide qu'une boucle for en C. Cela améliorerait la façon dont R copie les données en interne (sur certaines mesures par 13 fois). Le fil sur r-devel est ici: http://tolstoy.newcastle.edu.au/R/e10/devel/10/04/0148.html .

2.17 Quelles sont les plus petites différences de syntaxe entre data.frame et data.table?

  • DT[3] Fait référence à la 3ème ligne, mais DF[3] Fait référence à la 3ème colonne
  • DT[3,] == DT[3], Mais DF[,3] == DF[3] (Un peu confus)
  • Pour cette raison, nous disons que la virgule est facultative dans DT, mais pas facultative dans DF
  • DT[[3]] == DF[3] == DF[[3]]
  • DT[i,] Où i est un seul entier renvoie une seule ligne, tout comme DF[i,], Mais contrairement à un sous-ensemble matriciel à une seule ligne qui renvoie un vecteur.
  • DT[,j,with=FALSE] Où j est un seul entier renvoie un data.table à une colonne, contrairement à DF[,j] Qui retourne un vecteur par défaut
  • DT[,"colA",with=FALSE][[1]] == DF[,"colA"].
  • DT[,colA] == DF[,"colA"]
  • DT[,list(colA)] == DF[,"colA",drop=FALSE]
  • DT[NA] Renvoie 1 ligne de NA, mais DF[NA] Renvoie une copie de DF contenant NA tout au long.
  • Le symbole NA est de type logique dans R, et est donc recyclé par [.data.frame. L'intention était probablement DF[NA_integer_]. [.data.table Le fait automatiquement pour plus de commodité.
  • DT[c(TRUE,NA,FALSE)] traite le NA comme FAUX, mais DF[c(TRUE,NA,FALSE)] renvoie les lignes NA
    pour chaque NA
  • DT[ColA==ColB] Est plus simple que DF[!is.na(ColA) & !is.na(ColB) & ColA==ColB,]
  • data.frame(list(1:2,"k",1:4)) crée 3 colonnes, data.table crée une colonne de liste.
  • check.names Est par défaut TRUE dans data.frame Mais FALSE dans data.table, Pour plus de commodité.
  • stringsAsFactors est par défaut TRUE dans data.frame mais FALSE dans data.table, pour plus d'efficacité.
  • Puisqu'un cache de chaîne global a été ajouté à R, les éléments de caractères sont un pointeur vers la chaîne en cache unique et il n'y a plus d'avantage de performance de la conversion en facteur.
  • Les vecteurs atomiques dans les colonnes de liste sont réduits lors de l'impression à l'aide de "," dans data.frame, mais "," dans data.table avec une virgule de fin après le 6ème élément pour éviter l'impression accidentelle de gros objets incorporés.
  • Dans [.data.frame, Nous définissons très souvent drop=FALSE. Lorsque nous oublions, des bogues peuvent survenir dans les cas Edge où des colonnes uniques sont sélectionnées et tout d'un coup un vecteur est retourné plutôt qu'une seule colonne data.frame. Dans [.data.table, Nous en avons profité pour le rendre cohérent et le drop drop.
  • Lorsqu'un data.table est passé à un package data.table-unaware, ce package n'est concerné par aucune de ces différences; ça marche juste

Petite mise en garde

Il y aura peut-être des cas où certains packages utiliseront du code qui tombe quand on leur donne un data.frame, cependant, étant donné que data.table Est constamment maintenu pour éviter de tels problèmes, tous les problèmes qui peuvent survenir seront résolus rapidement.

Par exemple

  • base :: unname (DT) fonctionne à nouveau, selon les besoins de plyr :: melt (). Merci à Christoph Jaeckel pour ses reportages. Test ajouté.
  • Une méthode as.data.frame a été ajoutée pour ITime, afin que ITime puisse être passé à ggplot2 sans erreur, # 1713. Merci à Farrel Buchinsky pour ses reportages. Tests ajoutés. Les étiquettes d'axe de temps sont toujours affichées en secondes entières à partir de minuit; nous ne savons pas pourquoi ggplot2 n'invoque pas la méthode as.character d'ITime. Convertir ITime en POSIXct pour ggplot2, est une approche.
61
Amanda