2013-02-09 4 views
5

Ho un frame di dati con questi valori dummy vales e voglio fare lm regressione su di essi. Una delle variabili è una variabile continua raggruppati come mostrato di seguitoConversione di una variabile continua raggruppata in righe in R

df <- data.frame("y" = c(10, 11, 12, 13, 14), 
       "x" = as.factor(c("100-102", "103-105", "106-108", "109-111", "112-114"))) 

voglio regredire y ~ x, Un modo è quello di sostituire i fattori di x con i valori numerici medi. Questo è fatto facilmente usando l'espressione regolare.

Un altro modo è quello di creare le righe aggiuntive ed espandere il vostro set di dati in modo che appaia come questo

data.frame("y" = c(10, 10, 10, 11, 11, 11......), 
      "x" = c(100, 101, 102, 103, 104, 105......)) 

C'è una funzione che farà questo?

Sto pensando di creare prima variabili aggiuntive come x1, x2, x3 e quindi utilizzare il pacchetto reshape2 per convertire le colonne x in righe.

risposta

4

A data.table soluzione. Questo dovrebbe essere molto veloce anche sui grandi data.frame.

require(data.table) 
dt <- data.table(df, key="y") 
dt[, list(x=seq(sub("-.*$", "", x), sub(".*-", "", x))),by=y] 

Se si dispone di più colonne e non si desidera che ogni combinazioni mentre la divisione per colonna x, allora questo è il codice da utilizzare:

require(data.table) 
dt <- data.table(df) 
# get all column names except "x" 
key.cols <- setdiff(names(df), "x") 
# set the data.table columns to key.cols 
setkeyv(dt, key.cols) 
dt.out <- dt[, list(x=seq(sub("-.*$", "", x), sub(".*-", "", x))), by = key.cols] 

Questo dovrebbe dare ciò che vi aspettate.

+0

questa è una soluzione elegante e semplice. Grazie. btw come scalerà con set di dati con più colonne. Il mio esempio era un fittizio dataframe. il mio dataframe effettivo ha un sacco di colonne numeriche e una colonna fattore – MySchizoBuddy

+0

solo una colonna da dividere ma il set di dati ha più colonne, quindi le righe per tutte le altre colonne devono essere ripetute insieme a y – MySchizoBuddy

+1

funziona alla grande con poche righe di codice. Grazie – MySchizoBuddy

2
require(stringr) 
require(foreach) 

foreach(i=1:nrow(df), .combine=rbind) %do% { 
    s <- as.numeric(str_extract_all(df$x[i], "[0-9]+")[[1]]) 
    data.frame(y=rep(df$y[i], s[2]-s[1]+1), x=seq(s[1], s[2])) 
} 

Se il data.frame è davvero grande si può andare avanti con %dopar%.

+0

è stato veloce. non grande solo 2500 righe. – MySchizoBuddy

+0

'% do%' e '% dopar%' sono forniti dal pacchetto 'foreach'. – redmode