Quand faut-il utiliser un data.frame
, et quand est-il préférable d'utiliser un matrix
?
Les deux conservent les données dans un format rectangulaire, donc parfois ce n'est pas clair.
Existe-t-il des règles générales pour savoir quand utiliser quel type de données?
Réponses:
Une partie de la réponse est déjà contenue dans votre question: Vous utilisez des blocs de données si l'on peut s'attendre à ce que les colonnes (variables) soient de types différents (numérique / caractère / logique, etc.). Les matrices sont destinées aux données du même type.
Par conséquent, le choix matrice / data.frame n'est problématique que si vous avez des données du même type.
La réponse dépend de ce que vous allez faire des données dans data.frame / matrix. S'il doit être passé à d'autres fonctions, le type attendu des arguments de ces fonctions détermine le choix.
Aussi:
Les matrices sont plus efficaces en mémoire:
Les matrices sont une nécessité si vous prévoyez d'effectuer des opérations de type algèbre linéaire.
Les blocs de données sont plus pratiques si vous faites fréquemment référence à ses colonnes par leur nom (via l'opérateur compact $).
Les cadres de données sont également meilleurs à mon humble avis pour le reporting (impression) des informations tabulaires car vous pouvez appliquer le formatage à chaque colonne séparément.
la source
Quelque chose qui n'a pas été mentionné par @Michal est que non seulement une matrice est plus petite que la trame de données équivalente, l'utilisation de matrices peut rendre votre code beaucoup plus efficace que l'utilisation de trames de données, souvent considérablement. C'est l'une des raisons pour lesquelles en interne, de nombreuses fonctions R contraindront à des matrices de données qui sont dans des trames de données.
Les trames de données sont souvent beaucoup plus pratiques; on n'a pas toujours uniquement des morceaux atomiques de données qui traînent.
Notez que vous pouvez avoir une matrice de caractères; vous n'avez pas seulement besoin de données numériques pour construire une matrice dans R.
Lors de la conversion d'une trame de données en matrice, notez qu'il existe une
data.matrix()
fonction qui gère les facteurs de manière appropriée en les convertissant en valeurs numériques basées sur les niveaux internes. Le fait de forcer viaas.matrix()
produira une matrice de caractères si l'une des étiquettes de facteur n'est pas numérique. Comparer:J'utilise presque toujours une base de données pour mes tâches d'analyse de données car j'ai souvent plus que de simples variables numériques. Lorsque je code des fonctions pour des packages, je force presque toujours à matricer puis à formater les résultats sous forme de trame de données. C'est parce que les trames de données sont pratiques.
la source
@Michal: Les matrices ne sont pas vraiment plus efficaces en mémoire:
... sauf si vous avez un grand nombre de colonnes:
la source
data.frames
offrir plus de flexibilité sur les types de colonnes.data.frame(a = rnorm(1e6), b = sample(letters, 1e6, TRUE))
sera beaucoup plus petit (6x selon mon calcul rapide) en mémoire que lamatrix
version en raison de la coercition de type.La matrice est en fait un vecteur avec des méthodes supplémentaires. tandis que data.frame est une liste. La différence est due au vecteur vs liste. pour l'efficacité du calcul, tenez-vous-en à la matrice. Utiliser data.frame si vous le devez.
la source
la source
Je ne saurais trop insister sur la différence d'efficacité entre les deux! S'il est vrai que les DF sont plus pratiques dans certains cas d'analyse de données en particulier, ils permettent également des données hétérogènes, et certaines bibliothèques les acceptent uniquement, tout cela est vraiment secondaire à moins que vous n'écriviez un code unique pour une tâche spécifique.
Laisse moi te donner un exemple. Il y avait une fonction qui calculait le chemin 2D de la méthode MCMC. Fondamentalement, cela signifie que nous prenons un point initial (x, y), et itérons un certain algorithme pour trouver un nouveau point (x, y) à chaque étape, construisant de cette façon tout le chemin. L'algorithme implique le calcul d'une fonction assez complexe et la génération d'une variable aléatoire à chaque itération, donc quand il s'exécute pendant 12 secondes, j'ai pensé que c'était bien compte tenu de la quantité de choses qu'il fait à chaque étape. Cela étant dit, la fonction a collecté tous les points du chemin construit avec la valeur d'une fonction objectif dans un data.frame à 3 colonnes. Donc, 3 colonnes n'est pas si grand, et le nombre d'étapes était également plus que raisonnable 10 000 (dans ce genre de problèmes, les chemins d'une longueur de 1 000 000 sont typiques, donc 10 000 n'est rien). Alors, j'ai pensé à un DF 10, 000x3 n'est certainement pas un problème. La raison pour laquelle un DF a été utilisé est simple. Après avoir appelé la fonction, ggplot () a été appelé pour dessiner le chemin (x, y) résultant. Et ggplot () n'accepte pas de matrice.
Puis, à un moment donné par curiosité, j'ai décidé de changer la fonction pour collecter le chemin dans une matrice. Heureusement, la syntaxe des DF et des matrices est similaire, tout ce que j'ai fait a été de changer la ligne spécifiant df comme data.frame en l'initialisant en tant que matrice. Ici, je dois également mentionner que dans le code initial, le DF a été initialisé pour avoir la taille finale, donc plus tard dans le code de la fonction, seules les nouvelles valeurs ont été enregistrées dans des espaces déjà alloués, et il n'y a pas eu de surcharge pour ajouter de nouvelles lignes au DF. Cela rend la comparaison encore plus juste, et cela a également simplifié mon travail car je n'avais pas besoin de réécrire davantage dans la fonction. Une seule ligne change de l'allocation initiale d'un data.frame de la taille requise à une matrice de la même taille. Pour adapter la nouvelle version de la fonction à ggplot (), j'ai converti la matrice maintenant renvoyée en données.
Après avoir réexécuté le code, je ne pouvais pas croire le résultat. Le code s'exécute en une fraction de seconde! Au lieu d'environ 12 secondes. Et encore une fois, la fonction pendant les 10 000 itérations n'a lu et écrit des valeurs que dans des espaces déjà alloués dans un DF (et maintenant dans une matrice). Et cette différence concerne également la taille raisonnable (ou plutôt petite) de 10000x3.
Donc, si votre seule raison d'utiliser un DF est de le rendre compatible avec une fonction de bibliothèque telle que ggplot (), vous pouvez toujours le convertir en DF au dernier moment - travaillez avec des matrices autant que vous le souhaitez. Si, d'un autre côté, il existe une raison plus importante d'utiliser un DF, par exemple si vous utilisez un logiciel d'analyse de données qui nécessiterait une transformation constante des matrices en DF et inversement, ou si vous ne faites pas de calculs intensifs vous-même et utilisez uniquement le standard paquets (beaucoup d'entre eux transforment en fait un DF en matrice, font leur travail, puis transforment le résultat - ils font donc tout le travail d'efficacité pour vous), ou font un travail ponctuel pour que vous ne vous en souciez pas et ne vous sentiez pas plus à l'aise avec les DF, alors vous ne devriez pas vous soucier de l'efficacité.
Ou une autre règle plus pratique: si vous avez une question comme dans l'OP, utilisez des matrices, vous n'utiliserez donc les DF que lorsque vous n'avez pas une telle question (parce que vous savez déjà que vous devez utiliser des DF, ou parce que vous le faites pas vraiment de soins car le code est unique, etc.).
Mais en général, gardez toujours ce point d'efficacité à l'esprit en tant que priorité.
la source