2014-07-14 3 views
5

Vorrei sapere se è possibile annullare una stringa passata a un'espressione tramite il comando sostitutivo.Stringa unquote nel comando sostitutivo di R

In particolare, sto usando dplyr per filtrare e selezionare un frame di dati:

> w 
     subject sex response 
    1  1 M 19.08 
    2  2 M 16.46 
    ...  ... ... ... 
    6  6 M 23.60 
    7  7 M 23.96 
    8  8 F 22.48 
    9  9 F 25.79 
    ...  ... ... ... 
    16  16 F 26.66 

Di seguito produce il risultato desiderato:

> w %.% filter(sex == "M") %.% select(response)   
     response 
    1 19.08 
    2 16.46 
    3 22.81 
    4 18.62 
    5 18.75 
    6 23.60 
    7 23.96 

Ma io voglio fare questo in un più generale modo. Ciò che segue non produce il risultato richiesto poiché la stringa "sesso" è racchiusa tra virgolette.

sostitutiva (w%. Filtro% (y == "M"), la lista (y = pasta (nomi (w) [2])))

w %.% filter("sex" == "M") 
    > eval(substitute(w %.% filter(y == "M"), list(y = paste(names(w)[2])))) 
    [1] subject sex  response 
    <0 rows> (or 0-length row.names) 

posso sempre effettuare le seguenti operazioni:

eval(parse(text = paste("w %.% filter(", names(w)[2], " == 'M')"))) 

Ciò, tuttavia, guarda un po 'goffo.

Esistono modi più eleganti per farlo? Alla fine, mi piacerebbe concludere tutto in una funzione e renderla ancora più generale.

Qualsiasi aiuto/suggerimento sarebbe molto apprezzato.

Cordiali saluti,

Stefan

+0

Q Simile & A [** qui **] (http://stackoverflow.com/questions/22005419/dplyr-without-hard-coding-the-variable-names/22012451#22012451) – Henrik

+4

Prova 'as.nam e() ' – hadley

+0

Grazie, non sapevo di 'as.name()' finché Akrun non l'ha usato nella sua risposta. – Stefan

risposta

2

Può essere che si può provare:

w <- structure(list(subject = c(1L, 2L, 6L, 7L, 8L, 9L, 16L), sex = structure(c(2L, 
2L, 2L, 2L, 1L, 1L, 1L), .Label = c("F", "M"), class = "factor"), 
response = c(19.08, 16.46, 23.6, 23.96, 22.48, 25.79, 26.66 
)), .Names = c("subject", "sex", "response"), class = "data.frame", row.names = c("1", 
"2", "6", "7", "8", "9", "16")) 

Sulla base di commenti @ di Hadley

eval(substitute(w%>% filter(y=="M"), list(y=as.name(names(w)[2])))) 
+0

+1. Se vuoi aggiornare con un esempio (che stavo per postare), puoi usare 'mtcars%>% filter (get (incolla (nomi (mtcars) [2]), envir = as.environment (mtcars)) = = 4)%>% select (mpg) ':-) – A5C1D2H2I1M1N2O1R2T1

+0

@Ananda Mahto, grazie. Ho aggiornato con il set di dati mostrato nel post. Immagino che 'paste' non sia necessario. – akrun

+0

No. Non è - credo che stavo solo "traducendo" l'approccio dell'OP e non prestando veramente attenzione :-) – A5C1D2H2I1M1N2O1R2T1