77 Stimmen

Ungleiche Datenrahmen zusammenführen und fehlende Zeilen durch 0 ersetzen

Ich habe zwei data.frames, eines mit nur Zeichen und das andere mit Zeichen und Werten.

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e'))
df2 = data.frame(x=c('a', 'b', 'c'),y = c(0,1,0))
merge(df1, df2)
  x y
1 a 0
2 b 1
3 c 0 

Ich möchte df1 und df2 zusammenführen. Die Zeichen a, b und c wurden gut zusammengeführt und haben auch 0, 1, 0, aber d und e haben nichts. Ich möchte d und e auch in der Zusammenführungstabelle haben, mit der 0 0 Bedingung. Also für jede fehlende Zeile im df2 data.frame, muss die 0 in die df1 Tabelle gesetzt werden, wie:

  x y
1 a 0
2 b 1
3 c 0
4 d 0
5 e 0

117voto

Chase Punkte 65180

Werfen Sie einen Blick auf die Hilfeseite zum Zusammenführen. Die all Parameter können Sie verschiedene Arten von Zusammenführungen angeben. Hier wollen wir festlegen all = TRUE . Dadurch wird Merge Return NA für die Werte, die nicht übereinstimmen, die wir mit is.na() :

zz <- merge(df1, df2, all = TRUE)
zz[is.na(zz)] <- 0

> zz
  x y
1 a 0
2 b 1
3 c 0
4 d 0
5 e 0

Viele Jahre später aktualisiert, um eine Folgefrage zu beantworten

Sie müssen die Variablennamen in der zweiten Datentabelle identifizieren, die Sie nicht zusammenführen wollen - ich verwende setdiff() für diese. Sehen Sie sich das Folgende an:

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e', NA))
df2 = data.frame(x=c('a', 'b', 'c'),y1 = c(0,1,0), y2 = c(0,1,0))

#merge as before
df3 <- merge(df1, df2, all = TRUE)
#columns in df2 not in df1
unique_df2_names <- setdiff(names(df2), names(df1))
df3[unique_df2_names][is.na(df3[, unique_df2_names])] <- 0 

Erstellt am 2019-01-03 von der Reprex-Paket (v0.2.1)

7voto

Nick Sabbe Punkte 11524

Oder, als Alternative zum Code von @Chase, als neuer Plyr-Fan mit einem Hintergrund in Datenbanken:

require(plyr)
zz<-join(df1, df2, type="left")
zz[is.na(zz)] <- 0

4voto

Wojciech Sobala Punkte 7063

Eine weitere Alternative mit data.table.

BEISPIELDATEN

dt1 <- data.table(df1)
dt2 <- data.table(df2)
setkey(dt1,x)
setkey(dt2,x)

CODE

dt2[dt1,list(y=ifelse(is.na(y),0,y))]

3voto

sbha Punkte 8288

Angenommen, df1 hat alle Werte von x von Interesse, könnten Sie eine dplyr::left_join() zu verschmelzen und dann entweder eine base::replace() ou tidyr::replace_na() zu ersetzen. NA s als 0 s:

library(tidyverse)

# dplyr only:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace(y, is.na(y), 0))

# dplyr and tidyr:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace_na(y, 0))

# In the sample data column `x` is a factor, which will give a warning with the join. This can be prevented by converting to a character before the join:
df_new <- 
  left_join(df1 %>% mutate(x = as.character(x)), 
            df2 %>% mutate(x = as.character(x)), 
            by = 'x') %>% 
    mutate(y = replace(y, is.na(y), 0))

2voto

Ian E. Gorman Punkte 31

Ich habe die Antwort von Chase (Antwort vom 11. Mai '11 um 14:21 Uhr) verwendet, aber ich habe ein wenig Code hinzugefügt, um diese Lösung auf mein spezielles Problem anzuwenden.

Ich hatte ein Frame mit Raten (Benutzer, Download) und ein Frame mit Summen (Benutzer, Download), die nach Benutzer zusammengeführt werden sollten, und ich wollte jede Rate einbeziehen, auch wenn es keine entsprechende Summe gab. Es könnte jedoch keine fehlenden Gesamtwerte geben, in diesem Fall würde die Auswahl der Zeilen für die Ersetzung von NA durch Null fehlschlagen.

Die erste Zeile des Codes führt die Zusammenführung durch. In den nächsten beiden Zeilen werden die Spaltennamen im zusammengeführten Rahmen geändert. Die if-Anweisung ersetzt NA durch Null, aber nur, wenn es Zeilen mit NA gibt.

# merge rates and totals, replacing absent totals by zero
graphdata <- merge(rates, totals, by=c("user"),all.x=T)
colnames(graphdata)[colnames(graphdata)=="download.x"] = "download.rate"
colnames(graphdata)[colnames(graphdata)=="download.y"] = "download.total"
if(any(is.na(graphdata$download.total))) {
    graphdata[is.na(graphdata$download.total),]$download.total <- 0
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X