2015-05-15 9 views
6

Il mio frame di dati è composto da individui e dalla città in cui vivono in un determinato momento. Vorrei generare una matrice di origine-destinazione per ogni anno, che registra il numero di spostamenti da una città all'altra. Mi piacerebbe sapere:Creazione di matrici di destinazione di origine con R

  1. Come posso generare automaticamente le tabelle di origine-destinazione per ogni anno nel mio set di dati?
  2. Come posso generare tutte le tabelle nello stesso formato 5x5, 5 è il numero di città nel mio esempio?
  3. Esiste un codice più efficiente di quello che propongo di seguito? Ho intenzione di eseguirlo su un set di dati molto grande.

consideri il seguente esempio:

#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) 

Il mio migliore provare

#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")]  

Creazione di una tabella di origine-destinazione per 2007

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

Risultato

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

Se si sta mostrando in uscita dai dati simulati, è meglio usare 'set.seed' prima della simulazione (in modo che stiamo tutti guardando la stessa cosa). – Frank

risposta

6

È possibile suddividere i vostri dati da da id, eseguire i calcoli necessari sul telaio dati specifici id per afferrare tutte le mosse da quella persona, e poi ri-combinano:

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 
# ... 

Poiché questo codice usa calcoli vettoriali per ogni id, dovrebbe essere molto più veloce di un ciclo attraverso ogni riga del tuo frame dei dati come hai fatto nel codice fornito.

Ora si poteva afferrare le specifiche anni matrici 5x5 spostare utilizzando split e 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

Ottima discussione e buona risposta di @josliber. Mi chiedo se sia possibile avere un solo tavolo alla fine, sommando tutti gli anni. Ho modificato l'ultimo comando proposto da Josliber con 'a <- table (sposta $ da, sposta $ in)' ma posso ottenere un tavolo finale. che potrei scrivere.csv! Qualche idea? – Floni

+0

@Floni Questa è solo la 'tabella (sposta $ da, sposta $ in)'. Se questo non funziona, dovresti fare una nuova domanda con il pulsante "Chiedi domanda". – josliber

Problemi correlati