2016-04-03 5 views
1

Ich habe viele ähnliche Fragen gelesen, aber keine von ihnen sind ähnlich genug für mich, um die Antworten funktionieren zu lassen. Ich entschuldige mich, wenn das überflüssig ist und ich es einfach nicht sehen kann.füllen Sie NAs in einem Datenrahmen mit Daten von einem anderen, zwei ID-Variablen

Ich habe einen primären Datensatz und einen Sicherungsdatensatz. Wenn der primäre eine NA hat, möchte ich die Sicherung durchsehen, und wenn es einen Wert gibt, der mit full.place.name und Year übereinstimmt, möchte ich die NA durch diesen Wert ersetzen.

primary ist

Year Firearm.Homicide Firearm.Suicide Firearm.Unintentional full.place.name 
2010    0   <NA>      0 Adair County, KY 
2010    10    19     <NA> Adams County, CO 

backup ist

Year Firearm.Homicide Firearm.Suicide Firearm.Unintentional full.place.name 
2010    NA    1      1 Adair County, KY 
2010    NA    NA      0 Adams County, CO 

Was ich will, ist

Year Firearm.Homicide Firearm.Suicide Firearm.Unintentional full.place.name 
2010    0    1      0 Adair County, KY 
2010    10    19      0 Adams County, CO 

Ich habe versucht

library(data.table) 
setDT(primary); setDT(backup) 
primary[is.na(primary$Firearm.Homicide), primary$Firearm.Homicide := backup[backup, primary$Firearm.Homicide, on=c("Year", "full.place.name")]] 

Aber das fügte fünf Spalten bis zum Ende hinzu, und bekam keine der Werte richtig. Ich habe auch iffelse Aussagen und FillIn versucht, und ich bin nie nah gekommen. Hier sind fünf Datenzeilen:

primary<-structure(list(Year = c(2010, 2010, 2010, 2010, 2010), 
       Firearm.Homicide = c("0","10", "4", "3", NA), Firearm.Suicide = c(NA,"19", "5", "6", 
       NA), Firearm.Unintentional = c("0", NA, NA, "0", "0"), full.place.name = c("Adair County, KY", 
       "Adams County, CO", "Adams County, MS", "Adams County, PA", "Adams County, WI" 
      )), .Names = c("Year", "Firearm.Homicide", "Firearm.Suicide", 
       "Firearm.Unintentional", "full.place.name"), row.names = c(NA, 
       5L), class = "data.frame") 

backup<-structure(list(Year = c(2010, 2010, 2010, 2010, 2010), Firearm.Homicide = c(NA, 
      NA, 4, 3, 3), Firearm.Suicide = c(1, NA, NA, NA, NA), Firearm.Unintentional = c(1, 
      0, 1, NA, NA), full.place.name = c("Adair County, KY", "Adams County, CO", 
      "Adams County, MS", "Adams County, PA", "Adams County, WI")), .Names = c("Year", 
      "Firearm.Homicide", "Firearm.Suicide", "Firearm.Unintentional", 
      "full.place.name"), row.names = c(NA, 5L), class = "data.frame") 

Ich würde wirklich jede Hilfe zu schätzen wissen!

Antwort

2

Es gibt eine direkte Lösung dafür, wenn die beiden Datenrahmen immer die gleiche Struktur wie angegeben haben. Sie können Folgendes tun: primary[is.na(primary)] <- backup[is.na(primary)], wenn die Elemente in der Tabelle zuvor einander zugeordnet wurden. Hier ist eine Möglichkeit zum Sortieren Ihrer Daten.frame mit dplyr Paket unter der Annahme, dass Ihre Schlüsselspalten sind die "Year" und "full.place.name".

library(dplyr) primary <- arrange(primary, Year, full.place.name) %>% select(Year, Firearm.Homicide,Firearm.Suicide, Firearm.Unintentional, full.place.name) backup <- arrange(backup, Year, full.place.name) %>% select(Year, Firearm.Homicide, Firearm.Suicide, Firearm.Unintentional, full.place.name)

Es ist vielleicht nicht die optimale Art und Weise, es zu tun, aber es ist leicht zu verstehen.

+0

Sie sind jetzt nicht mehr aufeinander abgebildet, wie könnte ich das tun? – user5457414

+0

Sie können beide Datenrahmen zuerst nach den Schlüsselspalten sortieren, abhängig davon, was sie sind, hier, denke ich, sollten sie "Year" und "full.place.name" sein? – Psidom

0

Eine Option mit data.table wäre set. Die "Firearm" -Spalten in 'primary' sind character Klasse, während die entsprechenden Spalten in 'backup' numeric sind. Also müssen wir die class für diese Spalten in "primär" zu numeric vor dem Zuweisen der NA Werte in den "Firearm" Spalten in "primären" zu entsprechenden Werten aus dem "Backup" ändern.

Nach dem Verbindungsschritt mit on können wir Schleife über die „Feuerwaffe“ Spalten, wandeln die Spalten „numerische“, die „NA“ mit entsprechenden Werten in „i“ Spalte ersetzen und schließlich set die „i“ Spalten zu NULL.

#joining step 
dt <- setDT(primary)[backup, on = c("Year", "full.place.name")] 
#identify the Firearm columns with `grep` 
nm1 <- grep("^Firearm", names(primary), value=TRUE) 
#create a corresponding "i." column names vector from nm1 
nm2 <- paste0("i.", nm1) 
#loop through the columns 
for(j in seq_along(nm1)){ 
    #convert the Firearm columns from primary to `numeric` 
    set(dt, i = NULL, j= nm1[j], value = as.numeric(dt[[nm1[j]]])) 
    #replace the NA with corresponding values from "i" columns 
    set(dt, i = which(is.na(dt[[nm1[j]]])), j = nm1[j], 
     value = dt[[nm2[j]]][is.na(dt[[nm1[j]]])]) 
    #remove the i columns by assigning it to NULL 
    set(dt, i = NULL, j= nm2[j], value = NULL) 
} 


dt 
# Year Firearm.Homicide Firearm.Suicide Firearm.Unintentional full.place.name 
#1: 2010    0    1      0 Adair County, KY 
#2: 2010    10    19      0 Adams County, CO 
#3: 2010    4    5      1 Adams County, MS 
#4: 2010    3    6      0 Adams County, PA 
#5: 2010    3    NA      0 Adams County, WI 
0

Angenommen, Ihre Datensätze gleich sind und alle Namen identisch sind, sortiert (nach Ihrem Beispiel), dann

primary[is.na(primary)] <- backup[is.na(primary)] 
primary 
# Year Firearm.Homicide Firearm.Suicide Firearm.Unintentional full.place.name 
#1 2010    0    1      0 Adair County, KY 
#2 2010    10    19      0 Adams County, CO 
#3 2010    4    5      1 Adams County, MS 
#4 2010    3    6      0 Adams County, PA 
#5 2010    3   <NA>      0 Adams County, WI 
Verwandte Themen