2016-06-10 9 views
5

Vorrei chiamare tidyr::gather() all'interno di una funzione personalizzata, a cui passo una coppia di variabili di carattere che verranno utilizzate per rinominare le colonne key e value. per esempio.Passa la variabile a tidyr's gather per rinominare le colonne chiave/valore?

myFunc <- function(mydata, key.col, val.col) { 
    new.data <- tidyr::gather(data = mydata, key = key.col, value = val.col) 
    return(new.data)  
} 

Tuttavia, questo non funziona come desiderato.

temp.data <- data.frame(day.1 = c(20, 22, 23), day.2 = c(32, 22, 45), day.3 = c(17, 9, 33)) 

# Call my custom function, renaming the key and value columns 
# "day" and "temp", respectively 
long.data <- myFunc(mydata = temp.data, key.col = "day", val.col = "temp") 

# Columns have *not* been renamed as desired 
head(long.data) 
    key.col val.col 
1 day.1  20 
2 day.1  22 
3 day.1  23 
4 day.2  32 
5 day.2  22 
6 day.2  45 

output desiderato:

head(long.data) 
    day temp 
1 day.1 20 
2 day.1 22 
3 day.1 23 
4 day.2 32 
5 day.2 22 
6 day.2 45 

mia comprensione è che gather() utilizza i nomi delle variabili nudi per la maggior parte gli argomenti (come in questo esempio, utilizzando "key.col" come il nome della colonna in contrasto con il valore dimemorizzato in key.col). Ho tentato un certo numero di modi per passare un valore nella chiamata gather(), ma la maggior parte degli errori di restituzione. Ad esempio, queste tre varianti della chiamata gather() raggio myFunc ritorno Error: Invalid column specification (ignorando, per scopi illustrativi, il parametro value, che ha un comportamento identico):

gather(data = mydata, key = as.character(key.col) value = val.col) 

gather(data = mydata, key = as.name(key.col) value = val.col) 

gather(data = mydata, key = as.name(as.character(key.col)) value = val.col) 

Come una soluzione, ho solo rinomina le colonne seguenti chiamata a gather():

colnames(long.data)[colnames(long.data) == "key"] <- "day" 

Ma dato gather() 's funzionalità presunto per rinominare le colonne chiave/valore, come posso fare questo nel gather() chiamata entro una funzione personalizzata?

+0

Leggere '? Gather' e prestare attenzione alla sezione" Vedere anche ". Quindi, googling il nome della funzione appropriata probabilmente ti porterà [this] (http://stackoverflow.com/q/26429582/324364). – joran

risposta

1

Per dirla in una funzione è necessario utilizzare gather_() in questo modo.

myFunc <- function(mydata, key.col, val.col, gather.cols) { 
    new.data <- gather_(data = mydata, 
         key_col = key.col, 
         value_col = val.col, 
         gather_cols = colnames(mydata)[gather.cols]) 
    return(new.data)  
} 

temp.data <- data.frame(day.1 = c(20, 22, 23), day.2 = c(32, 22, 45), 
day.3 = c(17, 9, 33)) 
temp.data 


    day.1 day.2 day.3 
1 20 32 17 
2 22 22  9 
3 23 45 33 

# Call my custom function, renaming the key and value columns 
# "day" and "temp", respectively 

long.data <- myFunc(mydata = temp.data, key.col = "day", val.col = 
"temp", gather.cols = 1:3) 
# Columns *have* been renamed as desired 
head(long.data) 

    day temp 
1 day.1 20 
2 day.1 22 
3 day.1 23 
4 day.2 32 
5 day.2 22 
6 day.2 45 

Come detto, la differenza principale è in gather_ devi specificare le colonne che si desidera raccogliere con l'argomento gather_cols.

+1

Ottima spiegazione. Non mi rendevo conto che Wickham aveva infuso l'umile sottolineatura con un tale potere. – Jeff

1

La maggior parte (se non tutte) le funzioni di Haldey che utilizzano nomi di variabili vuoti come argomenti (come le funzioni di dplyr) hanno una versione function_ che utilizza una valutazione regolare e sono "idonee per la programmazione con". Quindi, che cosa avete bisogno dovrebbe essere solo:

myFunc <- function(mydata, key.col, val.col) { 
    tidyr::gather_(data = mydata, key_col = key.col, 
       value_col = val.col, gather_cols = colnames(mydata))   
} 

L'unica "catturare" qui è che è obbligatorio specificare la gather_cols, che non è necessario quando si utilizza gather o può essere fatto separatamente come ....

E poi:

> myFunc2(mydata = temp.data, key.col = "day", val.col = "temp") 
    day temp 
1 day.1 20 
2 day.1 22 
3 day.1 23 
4 day.2 32 
5 day.2 22 
6 day.2 45 
7 day.3 17 
8 day.3 9 
9 day.3 33 
+0

Buona spiegazione; l'inclusione di 'gather_cols' era pensosa. – Jeff

Problemi correlati