2015-02-03 2 views
12

Un'operazione incredibilmente comune per il mio tipo di dati è l'applicazione di un fattore di normalizzazione a tutte le colonne. Questo può essere fatto in modo efficiente utilizzando sweep o scale:Come faccio a spazzare colonne specifiche con dplyr?

normalized = scale(data, center = FALSE, scale = factors) 
# or 
normalized = sweep(data, 2, factors, `/`) 

Dove

data = structure(list(A = c(3L, 174L, 6L, 1377L, 537L, 173L), 
    B = c(1L, 128L, 2L, 1019L, 424L, 139L), 
    C = c(3L, 66L, 2L, 250L, 129L, 40L), 
    D = c(4L, 57L, 4L, 251L, 124L, 38L)), 
    .Names = c("A", "B", "C", "D"), 
    class = c("tbl_df", "data.frame"), row.names = c(NA, -6L)) 

factors = c(A = 1, B = 1.2, C = 0.8, D = 0.75) 

Tuttavia, come faccio a fare questo con dplyr, quando i miei dati ha colonne aggiuntive di fronte? Posso farlo in dichiarazioni separate, ma mi piacerebbe farlo in una pipeline. Questi sono i miei dati:

data = structure(list(ID = c(1, 2, 3, 4, 5, 6), 
    Type = c("X", "X", "X", "Y", "Y", "Y"), 
    A = c(3L, 174L, 6L, 1377L, 537L, 173L), 
    B = c(1L, 128L, 2L, 1019L, 424L, 139L), 
    C = c(3L, 66L, 2L, 250L, 129L, 40L), 
    D = c(4L, 57L, 4L, 251L, 124L, 38L)), 
    .Names = c("ID", "Type", "A", "B", "C", "D"), 
    class = c("tbl_df", "data.frame"), row.names = c(NA, -6L)) 

E mi piacerebbe mutare le colonne di dati senza toccare le prime due colonne. Normalmente posso farlo con mutate_each; tuttavia, come non posso passare i miei fattori di normalizzazione a tale funzione:

data %>% mutate_each(funs(./factors), A:D) 

Questo, ovviamente, presuppone che voglio dividere ogni colonna da factors, piuttosto che ogni colonna per il suo fattore di adattamento.

+0

Forse questo aiuta 'data%>% elenco (as.list (fattori))%>% Riduzione ('/',.)' – akrun

+0

@akrun No, questo non funziona affatto. –

+0

La mia soluzione era basata sul primo set di dati – akrun

risposta

11

Dato l'incoraggiamento di akrun, lasciatemi pubblicare ciò che ho fatto come risposta qui. Ho semplicemente pensato intuitivamente che potresti voler chiedere a R di indicare colonne con lo stesso nome per fare questo mutate_each. Ad esempio, se . indica la colonna, A, ho pensato che un'altra colonna denominata A da un altro data.frame potrebbe essere qualcosa che potrebbe essere una dplyr. Quindi, ho creato un data frame per factors quindi utilizzato mutate_each. Sembra che il risultato sia giusto. Dato che non ho una preparazione tecnica, temo di non poter fornire alcuna spiegazione. Spero che non ti dispiaccia.

factors <- data.frame(A = 1, B = 1.2, C = 0.8, D = 0.75) 

mutate_each(data, funs(./factors$.), A:D) 

# ID Type A   B  C   D 
#1 1 X 3 0.8333333 3.75 5.333333 
#2 2 X 174 106.6666667 82.50 76.000000 
#3 3 X 6 1.6666667 2.50 5.333333 
#4 4 Y 1377 849.1666667 312.50 334.666667 
#5 5 Y 537 353.3333333 161.25 165.333333 
#6 6 Y 173 115.8333333 50.00 50.666667 

EDIT

funziona in questo anche. Dato che il data frame è un caso particolare di elenco, questo non è forse sorprendente.

# Experiment 
foo <- list(A = 1, B = 1.2, C = 0.8, D = 0.75) 

mutate_each(data, funs(./foo$.), A:D) 

# ID Type A   B  C   D 
#1 1 X 3 0.8333333 3.75 5.333333 
#2 2 X 174 106.6666667 82.50 76.000000 
#3 3 X 6 1.6666667 2.50 5.333333 
#4 4 Y 1377 849.1666667 312.50 334.666667 
#5 5 Y 537 353.3333333 161.25 165.333333 
#6 6 Y 173 115.8333333 50.00 50.666667 
+0

Questo è quello che voglio. Tuttavia, lo trovo assolutamente confuso e non intuitivo.Questa è una terribile API, l'opposto di ciò che dplyr aspira ad essere. –

+0

@KonradRudolph Sono lieto di sapere che questo è quello che cerchi. Capisco la tua frustrazione. Inizialmente stavo facendo qualcosa di completamente diverso. Quindi, volevo solo essere "sciocco" un po 'e vedere cosa succede. Immagino che questo suggerisca che l'API non è necessariamente intuitiva per una vasta gamma di utenti. A proposito, ho imparato qualcosa di nuovo dalla tua domanda. Grazie mille. – jazzurro

+2

@KonradRudolph questo è come lo farei usando 'data.table' -' setDT (dati) [, nomi (fattori): = Mappa ("/", .SD, fattori), .SDcols = nomi (fattori) ] '- Non sono sicuro se ciò cancellerebbe la tua barra di intuitività. – eddi