Preliminari: questa domanda è per lo più di valore educativo, il compito effettivo è completato, anche se l'approccio non è del tutto ottimale. La mia domanda è se il codice qui sotto può essere ottimizzato per la velocità e/o implementato in modo più elegante. Forse usando pacchetti aggiuntivi, come plyr o reshape. Esegui sui dati effettivi ci vogliono circa 140 secondi, molto più alti dei dati simulati, poiché alcune delle righe originali non contengono nient'altro che NA, e devono essere fatti ulteriori controlli. Per confrontare, i dati simulati vengono elaborati in circa 30 secondi.Ottimizzazione: splitting dataframe in un elenco di dataframes, trasformazione dati per riga
Condizioni: l'insieme di dati contiene 360 variabili, 30 volte il set di 12. Diamo un nome loro V1_1, V1_2 ... (prima serie), V2_1, V2_2 ... (secondo set) e così via. Ogni set di 12 variabili contiene risposte dicotomiche (sì/no), in pratica corrispondenti a uno stato di carriera. Ad esempio: lavoro (sì/no), studio (sì/no) e così via, in totale 12 stati, ripetuti 30 volte.
Compito: il compito è quello di ricodificare ogni set di 12 variabili dicotomiche in una singola variabile con 12 categorie di risposta (ad esempio lavoro, studio ...). In definitiva dovremmo ottenere 30 variabili, ciascuna con 12 categorie di risposta.
dati: non posso postare il set di dati reali, ma qui è una buona approssimazione simulato:
randomRow <- function() {
# make a row with a single 1 and some NA's
sample(x=c(rep(0,9),1,NA,NA),size=12,replace=F)
}
# create a data frame with 12 variables and 1500 cases
makeDf <- function() {
data <- matrix(NA,ncol=12,nrow=1500)
for (i in 1:1500) {
data[i,] <- randomRow()
}
return(data)
}
mydata <- NULL
# combine 30 of these dataframes horizontally
for (i in 1:30) {
mydata <- cbind(mydata,makeDf())
}
mydata <- as.data.frame(mydata) # example data ready
mia soluzione:
# Divide the dataset into a list with 30 dataframes, each with 12 variables
S1 <- lapply(1:30,function(i) {
Z <- rep(1:30,each=12) # define selection vector
mydata[Z==i] # use selection vector to get groups of variables (x12)
})
recodeDf <- function(df) {
result <- as.numeric(apply(df,1,function(x) {
if (any(!is.na(df))) which(x == 1) else NA # return the position of "1" per row
})) # the if/else check is for the real data
return(result)
}
# Combine individual position vectors into a dataframe
final.df <- as.data.frame(do.call(cbind,lapply(S1,recodeDf)))
Tutto sommato, c'è un doppio * applica la funzione, una attraverso l'elenco, l'altra attraverso le righe del dataframe. Questo lo rende un po 'lento. Eventuali suggerimenti? Grazie in anticipo.
(+1) Domanda molto ben incorniciata. – Arun