2016-12-28 3 views
0

Ich habe diese Art von Datenrahmen:R Verwenden, wie leere Zellen eines Datenrahmens in Spalte B mit vorherigen Zeilenwert zu füllen, auf der Grundlage der Beziehung zu Spalte einen Wert

df <- data.frame(ID = rep(letters[1:5], each = 2), 
DESC = as.character(as.factor(rep(c("Petit", " ", "Small", " ", "Medium", " ", "Large", " ", "X-Large", " "), times = 1)))) 

Grundsätzlich muss ich die Paste Zeichenfolge in der Spalte 'DESC' mit den entsprechenden ID-Zeilen. Letztendlich sollte das Ergebnis wie folgt aussehen:

> df 
     ID DESC 
1 a Petit 
2 a Petit 
3 b Small 
4 b Small 
5 c Medium 
6 c Medium 
7 d Large 
8 d Large 
9 e X-Large 
10 e X-Large 

Bitte beachten Sie, dass mein tatsächlicher Datenrahmen nicht so einfach ist. Zum Beispiel habe ich identische Namen in der Spalte 'ID', die sich in der Anzahl der Zeilen von 1 bis 25 unterscheiden, in denen ich den Wert in 'DESC' für die entsprechende 'ID' einfügen muss. Also, ID 'a' kann 24 Zeilen in 'DESC' haben, in denen ich 'Petit' und 'b' füllen muss. Ich habe eine Zeile, in die ich 'Small' füllen muss.

Ich habe versucht, Skripte einschließlich Sapply, Grep, einfügen, aber fehlgeschlagen. Ich habe versucht, eine Schleife zu schreiben, aber es scheint, wenn ich auf df $ DESC es als Faktor gespeichert, obwohl ich es zu einem Zeichen Vektor gezwungen ... Jede Hilfe, Anweisung oder Punkt auf die Funktionen, die damit umgehen können, wird sehr geschätzt. Ich weiß, ich kann es einfach in Excel machen, aber das ist neben dem Punkt !! Ich versuche zu lernen, wie man das in R macht, kann keine Hilfe online zu diesem Thema finden.

Danke!

+0

dplyr Kontext, aber mit vielen Ansätzen: http://stackoverflow.com/q/23340150/4497050 – alistaire

Antwort

2

Wenn die IDs mit nicht leeren Werte in der ersten Position sortiert sind, können Sie eine einfache 'füllen' mit Reduce tun:

df$DESC = Reduce(function(x,y) if (y==' ') x else y, df$DESC, acc=T) 

> df 
# ID DESC 
# 1 a Petit 
# 2 a Petit 
# 3 b Small 
# 4 b Small 
# 5 c Medium 
# 6 c Medium 
# 7 d Large 
# 8 d Large 
# 9 e X-Large 
# 10 e X-Large 
0

Wenn Sie Paket verwenden können zoo:

df[df$DESC==" ","DESC"] <- NA # Correctly code missing values 
df$DESC <- zoo::na.locf(df$DESC) 

    ID DESC 
1 a Petit 
2 a Petit 
3 b Small 
4 b Small 
5 c Medium 
6 c Medium 
7 d Large 
8 d Large 
9 e X-Large 
10 e X-Large 
0

Hier ist eine Option mit dplyr

library(dplyr) 
df %>% 
    group_by(ID) %>% 
    mutate(DESC = first(DESC)) 
#  ID DESC 
# <fctr> <fctr> 
#1  a Petit 
#2  a Petit 
#3  b Small 
#4  b Small 
#5  c Medium 
#6  c Medium 
#7  d Large 
#8  d Large 
#9  e X-Large 
#10  e X-Large 

Oder mit data.table

library(data.table) 
setDT(df)[, DESC := DESC[1L], by = ID] 
0

Die Vorwärts füllen Lösungen sind schön, aber wenn es nicht sortiert ist, können wir alle ‚‘ Zeilen entfernen und Duplikate, dann das Ergebnis wieder zusammenführen:

merge(subset(df, select = -DESC),unique(df[df$DESC != ' ',]), by = 'ID') 

    ID DESC 
1 a Petit 
2 a Petit 
3 b Small 
4 b Small 
5 c Medium 
6 c Medium 
7 d Large 
8 d Large 
9 e X-Large 
10 e X-Large 

besser lesbar, in mehreren Schritte:

#find mapping 
mapping = unique(df[df$DESC != ' ',]) 

#remove DESC from data 
data = subset(df, select = -DESC) 

#merge 
merge(data, mapping, by = 'ID') 
Verwandte Themen