2014-11-27 7 views
5

Ich habe zwei Datenrahmen, die einige Spalten mit denselben Namen und andere mit anderen Namen haben. Die Datenrahmen in etwa so aussehen:R - Zusammenführen/Kombinieren von Spalten mit demselben Namen aber unvollständigen Daten

df1 
     ID hello world hockey soccer 
    1 1 NA NA  7  4 
    2 2 NA NA  2  5 
    3 3 10  8  8  23 
    4 4  4 17  5  12 
    5 5 NA NA  3  43 

df2  
     ID hello world football baseball 
    1 1  2  3  43  6 
    2 2  5  1  24  32 
    3 3 NA NA  2  23 
    4 4 NA NA  5  15 
    5 5  9  7  12  23 

Wie Sie, in 2 der gemeinsam genutzten Spalten sehen können („Hallo“ und „Welt“), einige der Daten in einem der Datenrahmen und dem Rest ist in der anderen.

Was ich versuche zu tun ist (1) die 2 Datenrahmen mit "ID" zusammenführen, (2) kombinieren alle Daten aus den "Hallo" und "Welt" Spalten in beiden Frames in 1 "Hallo" Spalte und 1 "Welt" -Spalte, und (3) der letzte Datenrahmen enthält auch alle anderen Spalten in den 2 Originalrahmen ("Hockey", "Fußball", "Fußball", "Baseball"). Also, ich mag das Endergebnis dies sein:

ID hello world hockey soccer football baseball 
1 1  2  3  7  4  43  6 
2 2  5  3  2  5  24  32 
3 3 10  8  8  23   2  23 
4 4  4 17  5  12   5  15 
5 5  9  7  3  43  12  23 

Ich bin ziemlich neu bei R so den einzigen Codes Ich habe versucht, sind Variationen merge und ich habe versucht, die Antwort, die ich hier gefunden, die waren basierend auf einer ähnlichen Frage: R: merging copies of the same variable. Meine Datensätze sind jedoch viel größer als die, die ich hier zeige (es gibt ungefähr 20 übereinstimmende Spalten (wie "Hallo" und "Welt") und 100 nicht übereinstimmende (wie "Hockey" und "Fußball")) also suche ich nach etwas, bei dem ich nicht alle manuell schreiben muss.

Irgendeine Idee, wenn das getan werden kann? Es tut mir leid ich nicht eine Probe meiner Bemühungen zur Verfügung stellen kann, aber ich weiß wirklich nicht, wo neben Start:

mydata <- merge(df1, df2, by=c("ID"), all = TRUE) 

die Datenrahmen zu reproduzieren:

df1 <- structure(list(ID = c(1L, 2L, 3L, 4L, 5L), hellow = c(2, 5, NA, NA, 9), world = c(3, 1, NA, NA, 7), football = c(43, 24, 2, 5, 12), baseball = c(6, 32, 23, 15, 23)), .Names = c("ID", "hello", "world", "football", "baseball"), class = "data.frame", row.names = c(NA, -5L)) 
df2 <- structure(list(ID = c(1L, 2L, 3L, 4L, 5L), hellow = c(NA, NA, 10, 4, NA), world = c(NA, NA, 8, 17, NA), hockey = c(7, 2, 8, 5, 3), soccer = c(4, 5, 23, 12, 43)), .Names = c("ID", "hello", "world", "hockey", "soccer"), class = "data.frame", row.names = c(NA, -5L)) 
+0

Ist es immer der Fall, wenn der Wert ist "NA" in "df1" hätte er einen Wert in "df2" (und umgekehrt)? – A5C1D2H2I1M1N2O1R2T1

+0

Ja, das ist immer der Fall. – abclist19

Antwort

5

Hier ist ein Ansatz Dazu gehören melt Ihre Daten, Verschmelzen der geschmolzenen Daten, und dcast, um es zu einer breiten Form zu bekommen. Ich habe Kommentare hinzugefügt, um zu verstehen, was vor sich geht.

## Required packages 
library(data.table) 
library(reshape2) 

dcast.data.table(
    merge(
    ## melt the first data.frame and set the key as ID and variable 
    setkey(melt(as.data.table(df1), id.vars = "ID"), ID, variable), 
    ## melt the second data.frame 
    melt(as.data.table(df2), id.vars = "ID"), 
    ## you'll have 2 value columns... 
    all = TRUE)[, value := ifelse(
     ## ... combine them into 1 with ifelse 
     is.na(value.x), value.y, value.x)], 
    ## This is your reshaping formula 
    ID ~ variable, value.var = "value") 
# ID hello world football baseball hockey soccer 
# 1: 1  2  3  43  6  7  4 
# 2: 2  5  1  24  32  2  5 
# 3: 3 10  8  2  23  8  23 
# 4: 4  4 17  5  15  5  12 
# 5: 5  9  7  12  23  3  43 
+0

Das funktioniert perfekt; Vielen Dank! – abclist19

+0

Eine Frage: Die Werte scheinen nicht numerisch zu sein. Gibt es eine Möglichkeit, dies zu erreichen und sie numerisch zu halten? – abclist19

+0

Ja, es gibt Spalten mit Zeichenspalten in meinen tatsächlichen Daten, aber nicht in den Spalten, in denen ich Schwierigkeiten beim Zusammenführen hatte. Alle Spalten, die geschmolzen wurden, scheinen jetzt Zeichenwerte zu sein. Irgendwie in der Nähe? – abclist19

2

Hier ist ein weiterer data.table Ansatz binäre merge mit

library(data.table) 
setkey(setDT(df1), ID) ; setkey(setDT(df2), ID) # Converting to data.table objects and setting keys 
df1 <- df1[df2][, `:=`(i.hello = NULL, i.world = NULL)] # Full left join 
df1[df2[complete.cases(df2)], `:=`(hello = i.hello, world = i.world)][] # Joining only on non-missing values 
# ID hello world football baseball hockey soccer 
# 1: 1  2  3  43  6  7  4 
# 2: 2  5  1  24  32  2  5 
# 3: 3 10  8  2  23  8  23 
# 4: 4  4 17  5  15  5  12 
# 5: 5  9  7  12  23  3  43 
2

@ Ananda-Mahto ‚s Antwort ist eleganter, aber hier ist mein Vorschlag:

library(reshape2) 
df1=melt(df1,id='ID',na.rm=TRUE) 
df2=melt(df2,id='ID',na.rm=TRUE) 
DF=rbind(df1,df2) 
# Not needeed, added na.rm=TRUE based on @ananda-mahto's valid comment 
# DF<-DF[!is.na(DF$value),] 
dcast(DF,ID~variable,value.var='value') 
+0

Vielen Dank für Ihren Kommentar, ich habe meine Antwort aktualisiert, um das zu integrieren. Dein ist noch eleganter :) – Nikos

Verwandte Themen