2012-07-31 17 views
6

Czytając R dla programistów Widziałem tę funkcjęPodstawową funkcją R

oddcount <- function(x) { 
    k <- 0 
    for (n in x) { 
    if (n %% 2 == 1) k <- k+1 
    } 
    return(k) 
} 

wolałbym napisać go w prostszy styl (czyli w Lisp)

(defn odd-count [xs] 
    (count (filter odd? xs))) 

widzę długość funkcji jest równoważny liczeniu i mogę pisać nieparzyste? więc czy są wbudowane funkcje mapowania/filtrowania/usuwania?

Odpowiedz

11

Bardziej R sposób robi to byłoby uniknąć pętli for i używać wektoryzacji:

oddcount <- function(x) { 
    sum(x %% 2) 
} 

Porównanie między x i 2 wyjściami wektora jako samego x jest wektorem. Suma niż oblicza sumę wektora, gdzie TRUE równa się 1, a FALSE jest równa zero. W ten sposób funkcja oblicza liczbę liczb nieparzystych w wektorze.

To już prowadzi do bardziej prostej składni, chociaż dla osób niezwiązanych z wektoryzacją, pętla for jest łatwiejsza do odczytania. Bardzo preferuję wektoryzowaną składnię, ponieważ jest znacznie krótsza. Wolałbym jednak użyć bardziej opisowej nazwy dla x, np. number_vector.

+1

W tym przypadku może to być nawet krótszy, nie naprawdę potrzebne '== 1 'od' '%% będzie tylko powrocie 0 i 1 roku. Użyj 'sum (x %% 2)'. To może być trochę szybsze, ponieważ nie generujesz logicznych i nie konwertujesz ich z powrotem na numeryczne. Niektórzy mogą znaleźć dłuższa wersja bardziej czytelny (a jeśli były, aby rozwinąć to patrząc na numery, które są lub nie są wielokrotnością czymś innym niż 2 wtedy trzeba dłuższą wersję. –

5

Należy przyjrzeć biblioteki funprog, który zawiera map, filter, reduce itp

+0

Dzięki, długość (Filter (odd_p, xs)) wydaje się wykonywać tę pracę, wydaje się, że zadaję złe pytanie w oparciu o ostatnią odpowiedź jednak :) – ChrisR

+0

Nie ma nic złego w użyciu 'funprog', ale za pomocą standardowego R można uzyskać taką samą krótkość w kodzie. –

+0

To dobra uwaga, @Paul. Próba wymuszenia na języku, który używa jednego paradygmatu (wektoryzowanego) na inny paradygmat (funkcjonalny), często powoduje niepotrzebnie pełny kod. –

12

W R, gdy pracujesz z wektorami, ludzie często wolą pracować nad całym wektorem naraz, zamiast przepuszczać go (patrz na przykład dyskusja this).

W pewnym sensie R ma wbudowany filtr i redukuje funkcje: sposób, w jaki można wybrać podzestawy wektora. Są bardzo przydatne w R, i jest kilka sposobów na zrobienie tego - pokażę ci parę, ale dowiesz się więcej, jeśli przeczytasz o R i spojrzysz na kod innych ludzi na stronie takiej jak ta. Rozważę też przeglądanie ?which i ?'[', które mają więcej przykładów niż tutaj.

Pierwszy sposób polega po prostu na wybraniu żądanych elementów.Można to wykorzystać, jeśli wiesz indeksy pierwiastków chcesz:

x <- letters[1:10] 
> x 
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" 

Jeśli chcemy tylko pięć pierwszych liter, możemy napisać:

x[1:5] 
x[c(1,2,3,4,5)] # a more explicit version of the above 

można również wybrać, które elementy, które nIE Chcą za pomocą znaku minus, na przykład:

x[-(6:10)] 

Innym sposobem wyboru elementów jest za pomocą wektora logiczną:

x <- 1:5 
selection <- c(FALSE, TRUE, FALSE, TRUE, FALSE) 
x[selection] # only the second and fourth elements will remain 

Jest to ważne, ponieważ możemy stworzyć taki wektor poprzez umieszczenie wektora w funkcji porównania:

selection <- (x > 3) 
> selection 
[1] FALSE FALSE FALSE TRUE TRUE 

x[selection] # select all elements of x greater than 3 
x[x > 3]  # a shorthand version of the above 

Po raz kolejny możemy wybrać przeciwieństwo porównania używamy (zauważ, że od jest logiczna, używamy ! i nie -):

x[!(x > 3)] # select all elements less than or equal to 3 

Jeśli chcesz robić porównań wektorowej, należy wziąć pod uwagę funkcję %in%. Na przykład:

x <- letters[1:10] 
> x %in% c("d", "p", "e", "f", "y") 
[1] FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE 

# Select all elements of x that are also "d", "p", "e", "f", or "y" 
x[x %in% c("d", "p", "e", "f", "y")] 
# And to select everything not in that vector: 
x[!(x %in% c("d", "p", "e", "f", "y"))] 

Powyższe przykłady to tylko kilka przykładów; Zdecydowanie polecam dokumentację. Wiem, że to jest długi słupek po już zaakceptowane odpowiedź, ale coś takiego jest bardzo ważna i rozumiejąc to będzie zaoszczędzić dużo czasu i bólu w przyszłości, jeśli jesteś nowy w R, więc pomyślałem, Udostępniam ci kilka sposobów na zrobienie tego z tobą.

+0

Dzięki, jest to z pewnością pomocne. – ChrisR

Powiązane problemy