Das ProblemR: For-Schleife zu lange
Ich habe einen Datensatz mit 3 Variablen: ein ID-Variable, eine Zeitvariable und eine numerische Variable X, die nur im Datensatz dargestellt wird, wenn es anders ist Null wie in der folgenden Tabelle.
time ID X
238 2007 A 28
239 2008 A 80
240 2014 A 178
241 2012 B 88
242 2011 C 369
243 2003 D 28
244 2004 D 80
Ich mag für jede ID in einem einzigartigen Datenrahmen mit einem lign haben und jedes Jahr zwischen 2001 und 2016 mit X = 0, wenn necesary. So wäre es eine Tabelle wie die folgenden sein:
time ID X
1 2001 A 0
2 2002 A 0
7 2007 A 28
8 2008 A 80
14 2014 A 178
17 2001 B 0
7 2012 B 88
ich gefunden habe keine Möglichkeit, es in der R Dokumentation zu tun, oder in diesem Forum
Wie ich vorgehen
zu lösen dieses Problem, ich hatte die Idee, in drei Schritten vorgehen:
1) I für jede ID-Nummer nur eine Zeile zu halten, egal welche Jahreszeit es ist
data2 = data%>%group_by(ID,X)%>%distinct(.keep_all = T)
, die der folgenden Tabelle führen:
time ID X
238 2007 A 28
241 2012 B 88
242 2011 C 369
243 2003 D 28
2) Dann duplizieren ich jede Zeile Beobachtung für jedes Jahr für jede ID
timebis = seq(from = 2001, to = 2016, by = 1)
dupl.data2 = data2[rep(1:nrow(data1), each=length(timebis)), ]
dupl.data1$X = 0
Ich habe jetzt 16 Beobachtungen zu haben.
3) Füllen Sie die dupl.data1 $ X-Säule mit einem Doppel for-Schleife
i=1
j=1
for(i in 1:length(dupl.data2$ID)){
for(j in 1:length(data$ID)){
if (dupl.data2$timebis[i]==data$time[j] & dupl.data2$ID[i]==data$ID[j])
{dupl.data2$X[i]=data$X[j]}
j=j+1
}
j=1
i=i+1
}
Fazit
Es funktioniert gut auf kleine Teilproben, aber meine ursprüngliche Datenbank hat etwa 300 000 Beobachtungen und der Datensatz mit Nullen ist viel größer. Ich müsste meine Codeeffizienz oder Ideen verbessern, um dieses Problem zu lösen.
Dank
So etwas wie 'newDf <- fusionieren (df, expand.grid (id = eindeutige (df $ id), year = 2001: 2014), durch = c ("id", "Jahr"), die alle = WAHR); df $ X [is.na (df $ X)] <- 0' wird funktionieren. – lmo
mit data.table, 'merge (setDT (data), setnames (data [, seq (2001, 2016), mit = data $ ID], c (" ID "," time ")), all = TRUE)' . Alles was getan werden muss, ist fehlende ersetzen. – user2957945