2012-11-02 10 views
5

Qualcuno sa come accelerare l'esecuzione del seguente comando? Voglio sostituire i valori numerici "mese" con una stringa di caratteri ... ad es. il mese 1 va a "Jul".accelerando in esecuzione se .. else loop in R

Questo comando è davvero molto lento in quanto il dataframe che sto cercando di implementarlo è enorme!

for (i in 1:length(CO2$month)){ 
    if(CO2$month[i]=='1') {CO2$months[i]<-'Jul'} else 
    if(CO2$month[i]=='2') {CO2$months[i]<-'Aug'} else 
    if(CO2$month[i]=='3') {CO2$months[i]<-'Sept'} else 
    if(CO2$month[i]=='4') {CO2$months[i]<-'Oct'} else 
    if(CO2$month[i]=='5') {CO2$months[i]<-'Nov'} else 
    if(CO2$month[i]=='6') {CO2$months[i]<-'Dec'} else 
    if(CO2$month[i]=='7') {CO2$months[i]<-'Jan'} else 
    if(CO2$month[i]=='8') {CO2$months[i]<-'Feb'} else 
    if(CO2$month[i]=='9') {CO2$months[i]<-'Mar'} else 
    if(CO2$month[i]=='10') {CO2$months[i]<-'Apr'} else 
    if(CO2$month[i]=='11') {CO2$months[i]<-'May'} else 
    if(CO2$month[i]=='12') {CO2$months[i]<-'Jun'} 
} 

risposta

7

È possibile farlo senza un ciclo e senza if-else:

set.seed(21) 
CO2 <- data.frame(month=as.character(sample(1:12,24,TRUE)), 
    stringsAsFactors=FALSE) 
MonthAbbRotated <- month.abb[c(7:12,1:6)] 
CO2$months <- MonthAbbRotated[as.numeric(CO2$month)] 

Se la colonna month non è proprio il carattere, questo è ancora più semplice:

set.seed(21) 
CO2 <- data.frame(month=sample(1:12,24,TRUE)) 
MonthAbbRotated <- month.abb[c(7:12,1:6)] 
CO2$months <- MonthAbbRotated[CO2$month] 
+0

Grande conoscere questo trucco! – Alex

+2

Qui ha un ritardo di 6 mesi nella sua domanda: 1 corrisponde a "Jul" e non a "Jan". Quindi qualcosa come 'month.abb [(as.numeric (CO2 $ month) +6) %% 12]' correggerebbe il lag. – plannapus

+0

@plannapus: ottima cattura, la modificherò nella mia risposta –

1
month =c("jul","aug","sep","oct","nov","dec","jan","feb","mar","apr","may","jun") 

for (i in 1:length(CO2$month)){ CO2$month[i] = month[as.integer(CO2$month[i])]} 
4

Potrei mancare qualcosa, ma perché non usare solo un fattore?

CO2$month <- factor(CO2$month, levels=1:12, labels=c("Jul","Aug","Sept","Oct","Nov","Dec","Jan","Feb","Mar","Apr","May","Jun"))

+0

+1 molto intelligente, ma l'interrogante avrebbe bisogno di racchiuderlo in 'as.character' per ottenere un risultato simile al loro esempio. Una versione leggermente più breve: 'factor (CO2 $ mese, livelli = c (7: 12,1: 6), labels = month.abb)' –

+0

È vero, ma potrebbe non interessarsi alla differenza tra un livello di fattore e una stringa. Se non lo fa dovrebbe anche essere più efficiente in termini di spazio (non sono sicuro se le stringhe di R interns). Se lo fa, allora può racchiuderlo in modo diverso come hai indicato – frankc

+0

vedi il mio commento alla tua risposta su month.abb. Op non * usa * * * * * * * * * * * * * * * * * * quella mappatura, anche se forse intendeva scrivere su – frankc

1

Questo potrebbe anche funzionare, anche se è per qualcosa in cui non c'è una funzione ordinata come month.abb da usare:

Mon <- data.frame(month=1:12, months=c("Jul","Aug","Sept","Oct","Nov","Dec", 
           "Jan","Feb","Mar","Apr","May","Jun")) 
CO2 <- merge(CO2, Mon, by="month", all.x=TRUE) 
+0

'month.abb' non è una funzione, è solo un oggetto predefinito. –

+0

Non pensare che faccia la differenza, ma è bello. –