120 votes

Création d’une dataframe R en mode ligne-de-ligne

Je voudrais construire un dataframe ligne par ligne dans l'arrêt R. j'ai fait quelques recherches, et tous, je suis venu avec l'idée de créer une liste vide, une liste d'index scalaire, alors à chaque fois ajouter à la liste d'une seule ligne, dataframe et de l'avance de l'index de liste par un. Enfin, do.call(rbind,) sur la liste.

Bien que cela fonctionne, il semble très lourd. N'est-il pas un moyen plus facile pour atteindre le même objectif?

Évidemment, je me réfère aux cas où je ne peux pas utiliser certains apply fonction et explicitement la nécessité de créer le dataframe, ligne par ligne. Au moins, il est un moyen d' push à la fin de la liste à la place d'un suivi explicite du dernier indice utilisé?

108voto

Dirk Eddelbuettel Points 134700

Vous pouvez les cultiver, ligne par ligne, en ajoutant ou en utilisant rbind().

Cela ne signifie pas que vous devriez. Dynamique des structures est l'une des moins efficaces façons de code dans R.

Si vous le pouvez, juste preserver toutes vos données.cadre avant:

N <- 1e4  # some magic number, possibly an overestimate

DF <- data.frame(num=rep(NA, N), txt=rep("", N),  # as many cols as you need
                 stringsAsFactors=FALSE)          # you don't know levels yet

puis, lors de vos opérations d'insérer une ligne à un moment

DF[i, ] <- c(1.4, "foo")

Cela devrait fonctionner pour des données arbitraires.cadre et d'être beaucoup plus efficace. Si vous overshot N vous pouvez toujours rétrécir, les lignes vides à la fin.

52voto

mbq Points 8963

On peut ajouter des lignes à `` :

par exemple

9voto

crippledlambda Points 8422

Il s’agit d’un bête exemple de comment utiliser sur la sortie de [qui est similaire à `` ]

J’ai utiliser cette construction assez souvent.

8voto

Allan Stokes Points 379

La raison pour laquelle j'aime Rcpp tellement, c'est que je n'arrive pas toujours comment R Core pense, et avec Rcpp, le plus souvent, je n'ai pas.

Philosophiquement parlant, vous êtes dans un état de péché en ce qui concerne le paradigme fonctionnel, qui essaie de faire en sorte que chaque valeur apparaît indépendante de toute autre valeur; de changer une valeur ne doit jamais provoquer un changement visible dans une autre valeur, la façon dont vous obtenez avec des pointeurs de partage de la représentation en C.

Les problèmes surviennent lors de la programmation fonctionnelle des signaux de petites embarcations pour se déplacer hors de la voie, et le petit artisanat répond "je suis un phare". Faire une longue série de petits changements à un grand objet que vous souhaitez traiter dans l'intervalle, vous met en place dans le phare de territoire.

Dans le C++ STL, push_back() est un mode de vie. Il n'essaie pas d'être fonctionnelle, mais il tente pour accueillir les idiomes de programmation commune efficacement.

Avec une certaine habileté dans les coulisses, on peut parfois s'arranger pour avoir un pied dans chaque monde. Instantané de base de systèmes de fichiers sont un bon exemple (qui a évolué à partir des concepts tels que l'union des montures, qui a également plis des deux côtés).

Si R Core voulions pour ce faire, le sous-jacent vecteur de stockage pourrait fonctionner comme une union de montage. Une référence pour le vecteur de stockage est peut-être valable pour les indices 1:N, tandis qu'une autre référence au même emplacement de stockage est valable pour les indices 1:(N+1). Il pourrait y avoir de stockage réservée pas encore valablement référencé par quoi que ce soit, mais pratique pour un rapide, push_back(). Vous ne violez pas la notion fonctionnelle lors de l'ajout de l'extérieur de la plage toute référence existante juge valable.

Finalement, ajouter les lignes de manière incrémentielle, vous exécutez hors de stockage réservé. Vous aurez besoin de créer de nouvelles copies de tout, avec la capacité de stockage multipliée par certains incrément. La STL implémentations j'ai utiliser ont tendance à se multiplier de stockage par 2 lors de l'extension de l'allocation. J'ai pensé que j'ai lu dans la R Internes qu'il existe une structure de mémoire où le stockage des incréments de 20%. De toute façon, les opérations de croissance se produisent avec une fréquence logarithmique par rapport au nombre total d'éléments ajoutés. Sur la méthode de l'amortissement, ce qui est normalement acceptable.

Que les trucs de derrière les coulisses aller, j'ai vu pire. Chaque fois que vous push_back() une nouvelle ligne sur le dataframe, au niveau supérieur de la structure de l'index doivent être copiés. La nouvelle ligne pourrait ajouter sur une représentation commune, sans impact sur toutes les anciennes valeurs fonctionnelles. Je ne pense même pas qu'il ne ferait que compliquer le garbage collector de beaucoup; car je ne suis pas proposer push_front() toutes les références sont préfixe références à l'avant de l'allocation d'un vecteur de stockage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X