R - Concaténer deux dataframes?

129

Étant donné deux dataframes aet b:

> a
           a           b           c
1 -0.2246894 -1.48167912 -1.65099363
2  0.5559320 -0.87898575 -0.15634590
3  1.8469466 -0.01487524 -0.53098215
4 -0.6875051  0.23880967  0.01824621
5 -0.6735163  0.75485292  0.44154092


> b
           a          c
1  0.4287284 -0.3295925
2  0.5201492  0.3341251
3 -2.6355570  1.7916780
4 -1.3645337  1.3642276
5 -0.4954542 -0.6660001

Existe-t-il un moyen simple de concaténer ces derniers afin de renvoyer une nouvelle trame de données du formulaire ci-dessous?

> new
           a                   b           c
1  -0.2246894   -1.48167912106676 -1.65099363
2   0.5559320  -0.878985746842256 -0.15634590
3   1.8469466 -0.0148752354840942 -0.53098215
4  -0.6875051   0.238809666690982  0.01824621
5  -0.6735163   0.754852923524198  0.44154092
6   0.4287284                  NA -0.32959248
7   0.5201492                  NA  0.33412510
8  -2.6355570                  NA  1.79167801
9  -1.3645337                  NA  1.36422764
10 -0.4954542                  NA -0.66600006

Je veux fusionner les dataframes, faire correspondre les en-têtes et insérer NApour les positions dans dataframe boù l'en-tête est manquant.

Darren J. Fitzpatrick
la source
3
Je suppose que vous avez déjà essayé merge()? Pourquoi ça ne marche pas?
Andrie
2
Je n'ai pas Andrie - tu donneras +1 à toi pour m'avoir fait faire ça!
Darren J.Fitzpatrick
16
Je suis confus. L'opération de Darren n'est pas une jointure - il n'y a pas de "produit cartésien". C'est plutôt une concaténation directe. Alors, comment les jointures aident-elles?
dfrankow

Réponses:

225

Vous voulez "rbind".

b$b <- NA
new <- rbind(a, b)

rbind exige que les trames de données aient les mêmes colonnes.

La première ligne ajoute la colonne b à la trame de données b.

Résultats

> a <- data.frame(a=c(0,1,2), b=c(3,4,5), c=c(6,7,8))
> a
  a b c
1 0 3 6
2 1 4 7
3 2 5 8
> b <- data.frame(a=c(9,10,11), c=c(12,13,14))
> b
   a  c
1  9 12
2 10 13
3 11 14
> b$b <- NA
> b
   a  c  b
1  9 12 NA
2 10 13 NA
3 11 14 NA
> new <- rbind(a,b)
> new
   a  b  c
1  0  3  6
2  1  4  7
3  2  5  8
4  9 NA 12
5 10 NA 13
6 11 NA 14
dfrankow
la source
9
Si vous obtenez l'union de plus de 2 blocs de données, vous pouvez les utiliser Reduce(rbind, list_of_data_frames)pour les écraser tous ensemble!
Yourpalal
1
si vous rbindvenez de la base pour une raison étrange: j'ai utilisérbind.data.frame
Boern
34

Essayez le package plyr :

rbind.fill(a,b,c)
Rnoob
la source
9
Évitez d'utiliser des packages externes pour des tâches simples.
Fernando
24
Plus clair et plus facile que de pirater des colonnes supplémentaires juste pour plaire à rbind; c'est la bonne voie à suivre. Il plyrn'est tout simplement pas judicieux d' éviter les packages extrêmement courants, comme lorsqu'il offre les bons outils pour le travail.
Jack Aidley
2
Cette fonction effectue automatiquement la fusion des facteurs. C'est nettement mieux que la réponse acceptée. plyrest un paquet commun terrible.
HelloWorld
23

vous pouvez utiliser la fonction

bind_rows(a,b)

de la bibliothèque dplyr

Adam Lee Perelman
la source
2
Contrairement à cbind ( rbind), cette fonction ne change pas le type de toutes les colonnes (lignes) en factorsi un vecteur de caractères est présent.
Azim
11

Voici une petite fonction simple qui reliera deux ensembles de données ensemble après avoir détecté automatiquement les colonnes manquantes de chacun et les avoir ajoutés avec tous les NAs.

Pour une raison quelconque, cela renvoie BEAUCOUP plus rapidement sur des ensembles de données plus volumineux que l'utilisation de la mergefonction.

fastmerge <- function(d1, d2) {
  d1.names <- names(d1)
  d2.names <- names(d2)

  # columns in d1 but not in d2
  d2.add <- setdiff(d1.names, d2.names)

  # columns in d2 but not in d1
  d1.add <- setdiff(d2.names, d1.names)

  # add blank columns to d2
  if(length(d2.add) > 0) {
    for(i in 1:length(d2.add)) {
      d2[d2.add[i]] <- NA
    }
  }

  # add blank columns to d1
  if(length(d1.add) > 0) {
    for(i in 1:length(d1.add)) {
      d1[d1.add[i]] <- NA
    }
  }

  return(rbind(d1, d2))
}
Mike Monteiro
la source
1
Cette petite fonction est la dynamite.
Dirk
Agréable. Je voulais juste poster la même réponse :-). Une amélioration: @Anton a lancé le NAto doubledans sa réponse. Ce serait bien lorsque le type de la nouvelle colonne était du même type que la colonne existante dans l'autre bloc de données. Peut-être via mode(d2[d2.add[i]]) <- mode(d1[d2.add[i]]). Mais je ne suis pas sûr que ce soit la manière appropriée.
daniel.heydebreck
3

Vous pouvez utiliser, rbindmais dans ce cas, vous devez avoir le même nombre de colonnes dans les deux tables, alors essayez ce qui suit:

b$b<-as.double(NA) #keeping numeric format is essential for further calculations
new<-rbind(a,b)
Anton
la source