2017-12-21 4 views
11

Ich habe die folgende Art von Datenrahmen:Füllung fehlt Ebene

Country <- rep(c("USA", "AUS", "GRC"),2) 
Year <- 2001:2006 
Level <- c("rich","middle","poor",rep(NA,3)) 
df <- data.frame(Country, Year,Level) 

df 
Country Year Level 
1  USA 2001 rich 
2  AUS 2002 middle 
3  GRC 2003 poor 
4  USA 2004 <NA> 
5  AUS 2005 <NA> 
6  GRC 2006 <NA> 

Ich mag die fehlende Werte mit dem richtigen Niveau Label in den letzten von der rechten Spalte füllen.

So sollte das erwartete Ergebnis so aussehen:

Country Year Level 
1  USA 2001 rich 
2  AUS 2002 middle 
3  GRC 2003 poor 
4  USA 2004 rich 
5  AUS 2005 middle 
6  GRC 2006 poor 
+0

Verwandte: [* Ersetzen von NAs durch den letzten Nicht-NA-Wert *] (https://StackOverflow.com/questions/7735647/Replacing-Nas-with-Latest-Non-Na-Wert) – Jaap

+0

Auch verwandt: [_Replace fehlende Werte (NA) mit den letzten nicht-NA von group_] (https://stackoverflow.com/q/23340150/4497050) – alistaire

Antwort

9

Wir können Gruppe von 'Land' und die Nicht-NA eindeutigen Wert

library(dplyr) 
df %>% 
    group_by(Country) %>% 
    dplyr::mutate(Level = Level[!is.na(Level)][1]) 
# A tibble: 6 x 3 
# Groups: Country [3] 
# Country Year Level 
# <fctr> <int> <fctr> 
#1  USA 2001 rich 
#2  AUS 2002 middle 
#3  GRC 2003 poor 
#4  USA 2004 rich 
#5  AUS 2005 middle 
#6  GRC 2006 poor 

Wenn wir bekommen geladen dplyr zusammen mit plyr, ist es besser, explizit anzugeben dplyr::mutate oder dplyr::summarise, so dass es die Funktion vonverwendet 10. Es gibt dieselben Funktionen in plyr und es könnte möglicherweise die Funktionen von dplyr maskieren, wenn beide geladen sind und ein anderes Verhalten erzeugen.

+3

Schöner Gedanke. Gut gemacht. Aber stellen wir hier nicht eine Annahme dar, wird es immer einen nicht na einmaligen Wert geben? Ich versuche nur zu verstehen. –

+0

@AbdulRahmanK Danke, es scheint, dass die OP einen einzigen einzigartigen Wert haben.Wenn es mehrere Werte gibt, vielleicht mutieren (Level = toString (unique (Level [! Is.na (Level)])) – akrun

+0

@akrun, ich denke, Ihre Antwort hat nicht funktioniert. Selbst für die MWE, vorausgesetzt, das Ergebnis war nicht das erwartete. aus diesem Grund [1] und bildet alle Länder auf "reich" ab. Versucht, eine Lösung zu finden, aber bisher hat noch nichts funktioniert. – msh855

5
library(dplyr) 

df %>% 
    group_by(Country) %>% 
    mutate(Level = replace(Level, is.na(Level), unique(na.omit(Level)))) 
Country Year Level 
    <fctr> <int> <fctr> 
1  USA 2001 rich 
2  AUS 2002 middle 
3  GRC 2003 poor 
4  USA 2004 rich 
5  AUS 2005 middle 
6  GRC 2006 poor 

Oder kurz und bündig, @ suchait Idee Anwendung na.locf zu verwenden:

df %>% 
    group_by(Country) %>% 
    mutate(Level = zoo::na.locf(Level)) 
+0

Nur neugierig - warum der Downvote? – eipi10

8

Sie können es usi tun ng data.table und zoo: -

library(data.table) 
library(zoo) 
setDT(df) 
df[, Level := na.locf(Level), by = Country] 

Diese Sie geben: -

Country Year Level 
1:  USA 2001 rich 
2:  AUS 2002 middle 
3:  GRC 2003 poor 
4:  USA 2004 rich 
5:  AUS 2005 middle 
6:  GRC 2006 poor 
12

In Basis R, könnten Sie ave() verwenden:

transform(df, Level = ave(Level, Country, FUN = na.omit)) 

# Country Year Level 
# 1  USA 2001 rich 
# 2  AUS 2002 middle 
# 3  GRC 2003 poor 
# 4  USA 2004 rich 
# 5  AUS 2005 middle 
# 6  GRC 2006 poor 

Eine weitere, genauere Möglichkeit ist eine Verknüpfung zu verwenden. Hier verschmelzen wir die Country Spalte mit den NA-weggelassenen Daten. Das Ergebnis ist das gleiche, nur in einer anderen Zeilenreihenfolge.

merge(df["Country"], na.omit(df)) 

# Country Year Level 
# 1  AUS 2002 middle 
# 2  AUS 2002 middle 
# 3  GRC 2003 poor 
# 4  GRC 2003 poor 
# 5  USA 2001 rich 
# 6  USA 2001 rich 
+0

Ich bekomme diese Fehlermeldung "Fehler in x [i] <- Wert [[j]]: Ersatz hat Länge Null", wenn ich es auf meine eigenen Datenrahmen anwenden – msh855

1

Eine Lösung und verwenden. Hier

library(dplyr) 
library(tidyr) 

df %>% 
    arrange(Country) %>% 
    fill(Level) %>% 
    arrange(Year) 
# Country Year Level 
# 1  USA 2001 rich 
# 2  AUS 2002 middle 
# 3  GRC 2003 poor 
# 4  USA 2004 rich 
# 5  AUS 2005 middle 
# 6  GRC 2006 poor 
+0

strrep (Buchstaben [23 ], 3) – AidanGawronski

+0

@AidanGawronski Cool! Danke für das Teilen. – www

1

ist eine weitere data.table Lösung, die Updates auf beitreten mit einer Lookup-Tabelle, die aus dem gegebenen Datensatz erstellt wird selbst:

library(data.table) 
setDT(df)[df[!is.na(Level)], on = .(Country), Level := Level][] 
Country Year Level 
1:  USA 2001 rich 
2:  AUS 2002 middle 
3:  GRC 2003 poor 
4:  USA 2004 rich 
5:  AUS 2005 middle 
6:  GRC 2006 poor