2015-03-09 12 views
6

Desidero scrivere una funzione che applica uno dei due metodi statistici diversi al suo input. Durante il processo, ho notato alcuni comportamenti di funzioni diverse che non capisco. La funzione voglio scrivere dovrebbe avere le seguenti caratteristiche:Vettore di corrispondenza dei valori predefiniti utilizzando match.arg() con o senza errore [R]

  • dovrebbe avere un vettore come valore di default (così l'utente può vedere quali sono i metodi disponibili)
  • se l'argomento viene lasciato a default valore, allora il primo dei due metodi deve essere usato
  • se l'utente manualmente fornisce un vettore di metodi, allora la funzione dovrebbe dare un errore

sostanza, voglio la funzione di B come nel caso di cor in R. Lì, si ha un valore predefinito method = c("pearson", "kendall", "spearman") e le funzioni hanno calcolato la correlazione di Pearson se method non è specificato. Se l'utente richiede più metodi contemporaneamente, la funzione restituisce un errore.

Dall'esame di cor, sembra essere fatto utilizzando match.arg(method). Questo comportamento è illustrato qui:

x <- y <- 1:5 

cor(x, y, method="pearson") 
# = 1 
cor(x, y, method="kendall") 
# = 1 
cor(x, y, method=c("pearson","kendall")) 
# gives an error 

Ho provato a scrivere la mia propria funzione, utilizzando anche match.arg(method), ma mi sono reso conto che il risultato è in qualche modo diverso. Anche quando si sceglie un vettore per method, la funzione non termina con un errore, ma restituisce i risultati del primo metodo.

Questo è illustrato qui:

myfun <- function(x, method=c("add","multiply")){ 
    method <- match.arg(method) 
    if(method=="add") return(sum(x)) 
    if(method=="multiply") return(prod(x)) 
} 

x <- 1:5 

myfun(x, method="add") 
# = 15 
myfun(x, method="multiply") 
# = 120 
myfun(x, method=c("add","multiply")) 
# = 15 

Non capisco questo comportamento, e sarei lieto se potesse dare una mano qui. Dai miei tentativi su Google, mi rendo conto che potrebbe essere correlato a una valutazione non standard, ma non posso ancora mettere insieme due e due.

Grazie in anticipo, il vostro aiuto è molto apprezzato!

Cheers!

EDIT:

potevo anche ri-frase la mia domanda:

Che magia potente fa cor fanno che restituisce la correlazione di Pearson, quando method non viene fornito, ma che restituisce un errore quando method = c("pearson", "kendall", "spearman") è specificato esplicitamente?

risposta

6

Se choices e args sono uguali in match.arg, viene restituito il primo elemento. Altrimenti arg deve essere di lunghezza 1. Da match.arg:

Dal argomento di default corrispondente imposterà arg alle scelte, ciò è consentito come eccezione alla 'lunghezza a meno several.ok è TRUE' regola, e restituisce il primo elemento.

match.arg(c("pearson", "kendall", "spearman"), c("pearson", "kendall", "spearman")) 
## [1] "pearson" 
match.arg(c("pearson", "kendall"), c("pearson", "kendall", "spearman")) 
## Error in match.arg(c("pearson", "kendall"), c("pearson", "kendall", "spearman")) : 
## 'arg' must be of length 1 

È possibile ottenere il comportamento desiderato utilizzando un argomento fittizio:

myfun <- function(x, method=c("add","multiply","other.return.error")){ 
    method <- match.arg(method) 
    if("other.return.error" %in% method) stop("this option should not be used") 
    if(method=="add") return(sum(x)) 
    if(method=="multiply") return(prod(x)) 
} 
+0

Ho capito bene che il comportamento di 'cor' e' myfun' differisce perché ho testato un vettore a due elementi, dove 'cor' restituisce un errore perché il suo argomento predefinito è di lunghezza 3, e' myfun' funziona senza errori perché il suo argomento predefinito è di lunghezza 2? – SimonG

+0

Il comportamento "desiderato" in realtà non faceva parte della domanda. L'ho risolto io stesso, semplicemente controllando che 'method' venga fornito usando' missing (method) 'e stampando un errore usando' stop' se è stato fornito con length> 1. In questo modo non ho bisogno di un argomento fittizio che mostra anche nelle pagine man. – SimonG

+0

Sì, il comportamento di 'cor' e' myfun' differisce a causa della lunghezza degli argomenti predefiniti. E ho capito che il comportamento desiderato non faceva parte della domanda. Ho aggiunto una soluzione non necessariamente per te, ma per altre persone che potrebbero trovare questa domanda e non hanno ancora trovato una soluzione soddisfacente. – shadow

1

La questione principale è stato risposto con @shadow (vedi sopra).

Un altro modo di ottenere il comportamento desiderato per myfun è quello di eseguire un controllo se method viene fornito o meno e la stampa un errore se fosse esplicitamente fornito con più di un elemento.

myfun <- function(x, method=c("add","multiply")){ 
    if(!missing(method) & length(method)>1) stop("Only one 'method' allowed.") 
    method <- match.arg(method) 
    if(method=="add") return(sum(x)) 
    if(method=="multiply") return(prod(x)) 
} 

x <- 1:5 

myfun(x) 
# = 15 
myfun(x, method="add") 
# = 15 
myfun(x, method="multiply") 
# = 120 
myfun(x, method=c("add","multiply")) 
# gives error 

Questo elude l'eccezione match.arg indicate da @shadow da cui fornire un vettore per la funzione può non causa un errore. Invece, questo errore viene dato subito.

Problemi correlati