2016-08-09 16 views
5

Mamy funkcję, która wymaga wielu argumentów bez wartości domyślnych dla żadnego z nich. Jednakże, nawet jeśli niektóre z nich nie są określone, funkcja zwraca wartość, jeśli te parametry są używane tylko do podziału macierzy (i ewentualnie innych typów). Zastanawiają nas, dlaczego tak jest - czy ktoś może pomóc?Wartości funkcji R bez wartości domyślnych, które są ignorowane

szczególności, dlaczego następujący kod nie zwróci błąd, ale sumy na całej matrycy i ignoruje j:

foo <- function(mat, j){ 
    v <- sum(mat[,j]) 
    v 
} 

foo(mat = matrix(1:4,3,4)) 

Odpowiedz

2

Zgaduję, że argument nie zostanie nigdy oceniony.

foo <- function(x) 
    bar(x) 

bar <- function(y) 
    missing(y) 

foo() 
#[1] TRUE 
foo(43) 
#[1] FALSE 

Funkcja wewnętrzna, w przypadku [, który ma argumenty formalne i, j, ..., drop = FALSE, najprawdopodobniej sprawdza, czy argument j brakuje, a jeśli go brakuje, że nie stara się go oceniać.

+0

Więc gdy' R' nie może znaleźć wartości dla 'j' w swoim środowisku, po prostu zignoruje, że' j' miało wskazywać na kolumnę (wiersz)? Czy tak jest zawsze w przypadku indeksowania obiektu? –

+2

Nie, gdy R ocenia, że ​​'j' i' j' nie znajduje się w bieżącym lub w środowiskach macierzystych, powoduje to błąd. W tym przypadku nie ma błędu, ponieważ 'j' nie jest oceniany. Argumenty R są oceniane w środowisku funkcji, gdy (jeśli) są potrzebne, a niektóre specjalne funkcje, takie jak 'missing()', nie oceniają w ogóle ich argumentów. –

4

Według this blog opcjonalne argumenty bez domyślnych brakuje od wewnątrz funkcji. Testowanie dla niego zwraca TRUE.

foo <- function(mat, j){ 
    v <- sum(mat[,j]); print(missing(j)) 
    v 
} 
foo(mat = matrix(1:4,3,4)) 
[1] TRUE 
[1] 30 

Nie wiedząc co specyfika były eksperymentowałem z sum nieco i to jest to, co widać.

sum(matrix(1:4,3,4)[,NA]) 
[1] NA 
sum(matrix(1:4,3,4)[,NULL]) 
[1] 0 
sum(matrix(1:4,3,4)[,]) 
[1] 30 

Jeśli nie określimy żadnego indeksu dla macierzy, sum podsumuje wszystkie jej wartości.

Od czytania bloga i małego eksperymentu, myślę, że twoje niestandardowe funkcje działają w przypadkach, gdy użyta funkcja przetwarza dostarczone dane i jest w stanie pracować z brakującymi argumentami. W przypadku podsekcji macierzy zachowanie z brakującymi argumentami dla podzbiorów polega na tym, że funkcja wykonuje operację na całym zbiorze danych.

+2

Po prostu: macierz (1: 4,3,4) [, NA] 'i' macierz (1: 4,3,4) [, NULL] 'ustawia macierz na wszystkie' NA' i na ' NULL' odpowiednio. Stąd wynik "sumy". – aichao

+1

Mogliśmy zobaczyć, co się dzieje, definiując funkcję 'foo2 = function (mat, j) substitute (sum (mat [, j])), a następnie użyj jej' foo2 (matrix (1: 4, 3, 4)) ' –

0

Oprócz @nya odpowiedź:

Można tego uniknąć poprzez wstawienie if -statement wewnątrz funkcji, który ocenia, czy wartość dla j został dostarczony po wywołaniu funkcji. Jeśli nie zostanie podana żadna wartość, funkcja wygeneruje błąd:

foo <- function(mat, j){ 
    if(missing(j)){    # Check if argument for j has been supplied 
     error("j is not inserted") 
    } else{ 
     v <- sum(mat[,j]) 
     return(v) 
    } 
    } 
Powiązane problemy