2015-05-15 11 views
6

Mein Datenrahmen besteht aus Personen und der Stadt, in der sie zu einem bestimmten Zeitpunkt leben. Ich möchte für jedes Jahr eine Ursprungs-Ziel-Matrix generieren, die die Anzahl der Züge von einer Stadt zur anderen aufzeichnet. Ich würde gerne wissen:Erstellen von Ursprungs-Ziel-Matrizen mit R

  1. Wie kann ich die Herkunft-Ziel-Tabellen für jedes Jahr automatisch in meinem Datensatz generieren?
  2. Wie kann ich alle Tabellen im selben 5x5-Format generieren, wobei 5 die Anzahl der Städte in meinem Beispiel ist?
  3. Gibt es einen effizienteren Code als das, was ich unten vorschlage? Ich beabsichtige, es auf einem sehr großen Datensatz auszuführen.

Betrachten Sie das folgende Beispiel:

#An example dataframe 
id=sample(1:5,50,T) 
year=sample(2005:2010,50,T) 
city=sample(paste(rep("City",5),1:5,sep=""),50,T) 
df=as.data.frame(cbind(id,year,city),stringsAsFactors=F) 
df$year=as.numeric(df$year) 
df=df[order(df$id,df$year),] 
rm(id,year,city) 

mein Bestes versuchen,

#Creating variables 
for(i in 1:length(df$id)){ 
    df$origin[i]=df$city[i] 
    df$destination[i]=df$city[i+1] 
    df$move[i]=ifelse(df$orig[i]!=df$dest[i] & df$id[i]==df$id[i+1],1,0) #Checking whether a move has taken place and whether its the same person 
    df$year_move[i]=ceiling((df$year[i]+df$year[i+1])/2) #I consider that the person has moved exactly between the two dates at which its location was recorded 
} 
df=df[df$move!=0,c("origin","destination","year_move")]  

einen Ursprung Zieltabelle erstellen für 2007

yr07=df[df$year_move==2007,] 
table(yr07$origin,yr07$destination) 

Ergebnis

 City1 City2 City3 City5 
    City1  0  0  1  2 
    City2  2  0  0  0 
    City5  1  1  0  0 
+2

Wenn Sie die Ausgabe von simulierten Daten sind zeigt, ist es am besten 'set.seed' vor der Simulation zu verwenden (so dass wir alle dasselbe sehen). – Frank

Antwort

6

Sie Ihre Daten aus von id aufteilen, die notwendigen Berechnungen auf der id-spezifischen Datenrahmen führen alle Bewegungen von dieser Person zu greifen, und dann neu kombinieren:

spl <- split(df, df$id) 
move.spl <- lapply(spl, function(x) { 
    ret <- data.frame(from=head(x$city, -1), to=tail(x$city, -1), 
        year=ceiling((head(x$year, -1)+tail(x$year, -1))/2), 
        stringsAsFactors=FALSE) 
    ret[ret$from != ret$to,] 
}) 
(moves <- do.call(rbind, move.spl)) 
#  from to year 
# 1.1 City4 City2 2007 
# 1.2 City2 City1 2008 
# 1.3 City1 City5 2009 
# 1.4 City5 City4 2009 
# 1.5 City4 City2 2009 
# ... 

Da dieser Code Für jede ID werden Vektorberechnungen verwendet. Sie sollten viel schneller sein als das Durchlaufen jeder Zeile Ihres Datenrahmens wie im bereitgestellten Code.

Nun könnte man die jahresspezifische 5x5 bewegen Matrizen greifen mit split und table:

moves$from <- factor(moves$from) 
moves$to <- factor(moves$to) 
lapply(split(moves, moves$year), function(x) table(x$from, x$to)) 
# $`2005` 
#   
#   City1 City2 City3 City4 City5 
# City1  0  0  0  0  1 
# City2  0  0  0  0  0 
# City3  0  0  0  0  0 
# City4  0  0  0  0  0 
# City5  0  0  1  0  0 
# 
# $`2006` 
#   
#   City1 City2 City3 City4 City5 
# City1  0  0  0  1  0 
# City2  0  0  0  0  0 
# City3  1  0  0  1  0 
# City4  0  0  0  0  0 
# City5  2  0  0  0  0 
# ... 
+0

Sehr gute Diskussion und gute Antwort von @josliber. Ich frage mich, ob es möglich ist, nur einen Tisch am Ende zu haben, summiert alle Jahre. Ich bearbeitete den letzten von Josliber vorgeschlagenen Befehl mit 'a <- Tabelle (verschiebt $ von, bewegt $ zu)' aber ich kann einen Final Table bekommen. das könnte ich schreiben.csv! Irgendwelche Ideen? – Floni

+0

@Floni Das ist nur 'table (verschiebt $ von, verschiebt $ zu)'. Wenn das für Sie nicht funktioniert, sollten Sie eine neue Frage mit der Schaltfläche "Frage stellen" stellen. – josliber

Verwandte Themen