2015-03-09 32 views
6

Chcę napisać funkcję, która stosuje jedną z dwóch różnych metod statystycznych do jej wprowadzania. W trakcie tego procesu zauważyłem pewne zachowanie różnych funkcji, których nie rozumiem. Funkcja Chcę napisać powinien posiadać następujące właściwości:Dopasowywanie wektora wartości domyślnych za pomocą match.arg() z lub bez błędu [R]

  • powinien mieć wektor jako wartość domyślną (dzięki czemu użytkownik może sprawdzić, które metody są dostępne)
  • jeśli argument jest pozostawiony na domyślny wartość, to pierwszy z dwóch metod należy stosować
  • jeśli użytkownik ręcznie dostarcza wektor metod, to funkcja powinna dać błąd

Zasadniczo chcę funkcja do b Podobnie jak cor ma w R. Tam masz domyślną wartość method = c("pearson", "kendall", "spearman"), a funkcje obliczyły korelację Pearsona, jeśli nie podano wartości method. Jeśli użytkownik poprosi o kilka metod naraz, funkcja zwróci błąd.

Patrząc na cor, wydaje się, że jest to zrobione przy użyciu match.arg(method). Takie zachowanie jest zilustrowany tutaj:

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 

Próbowałem pisać moją własną funkcję, również za pomocą match.arg(method), ale zdałem sobie sprawę, że wynik jest jakoś inaczej. Nawet przy wyborze wektora dla method funkcja nie kończy się z błędem, ale zwraca wyniki pierwszej metody.

Ilustruje to tutaj:

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 

Nie rozumiem tego zachowania, i byłbym zadowolony, gdyby mógł mi pomóc tutaj. Z moich prób Google, wiem, że może to być związane z niestandardową oceną, ale nie mogę jeszcze połączyć dwóch i dwóch razem.

Z góry dziękujemy za pomoc!

Pozdrawiam!

EDIT:

mogłem również ponowne zdanie moje pytanie:

Co potężne czary nie cor zrobić, że zwraca korelacji Pearsona gdy method nie jest dostarczany, ale zwraca błąd, gdy method = c("pearson", "kendall", "spearman") jest jawnie określony?

Odpowiedz

6

Jeśli choices i args są takie same w match.arg, to zwracany jest pierwszy element. Inaczej arg musi mieć długość 1. Od match.arg:

Ponieważ dopasowywanie domyślnym argumentem ustawi arg do wyborów, to jest dozwolone jako wyjątek „długości jednego chyba several.ok jest PRAWDA” reguła, i zwraca pierwszy element.

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 

można uzyskać pożądane zachowanie przy użyciu manekina argumentu:

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

Czy rozumiem poprawnie, że zachowanie 'cor' i' myfun' różni się, ponieważ testowałem pod kątem wektora dwuelementowego, w którym 'cor' zwraca błąd, ponieważ jego domyślny argument ma długość 3 i' myfun' działa bez błędu, ponieważ jego domyślny argument ma długość 2? – SimonG

+0

"Pożądane" zachowanie w rzeczywistości nie było częścią pytania. Sam to rozwiązałem, po prostu sprawdzając, czy 'metoda' jest dostarczona za pomocą' missing (method) 'i drukując błąd za pomocą' stop', jeśli został dostarczony z długością> 1. W ten sposób nie potrzebuję fałszywego argumentu, który pokaż także na stronach man. – SimonG

+0

Tak, zachowanie 'cor' i' myfun' różni się ze względu na długość domyślnych argumentów. I dostaję, że pożądane zachowanie nie było częścią tego pytania. Dodałem rozwiązanie niekoniecznie dla ciebie, ale dla innych osób, które mogą znaleźć to pytanie i jeszcze nie znalazły satysfakcjonującego rozwiązania. – shadow

1

Główne pytanie odpowiedzieli @shadow (patrz wyżej).

Innym sposobem na uzyskanie pożądanego zachowania na myfun jest dokonać sprawdzenia czy method lub nie jest zasilany i drukowanie błąd, jeśli to było wyraźnie dostarczany z więcej niż jednego elementu.

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 

ten omija wyjątek w match.arg podkreślił @shadow przez który dostarcza wektor do funkcji może nie przyczyną błędu. Zamiast tego ten błąd jest podawany od razu.