Załóżmy, że mam macierz by 2 i funkcję, która jako jeden z argumentów przyjmuje wektor 2. Chciałbym zastosować tę funkcję do każdego wiersza macierzy i uzyskać n-wektor. Jak to zrobić w R?
Na przykład chciałbym obliczyć gęstość standardowego rozkładu normalnego 2D w trzech punktach:
bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out <- rbind(c(1, 2), c(3, 4), c(5, 6))
Jak zastosować funkcję do każdego wiersza out
?
Jak przekazać wartości dla innych argumentów oprócz punktów do funkcji w sposób określony przez Ciebie?
apply()
- zamiata po wierszu (gdy drugi argument ma wartość 1, w przeciwnym razie po kolumnie), a bieżący wiersz (lub kolumna) jest zawsze pierwszym argumentem. Tak się definiuje.MARGIN
argument. Tutaj oznacza zastosowanie funkcji do wierszy (pierwszy wymiar wdim(M)
). Gdyby było 2, zastosowałoby funkcję do kolumn.Jeśli chcesz zastosować typowe funkcje, takie jak suma lub średnia, powinieneś użyć
rowSums
lub,rowMeans
ponieważ są one szybsze niżapply(data, 1, sum)
podejście. W przeciwnym razie trzymaj sięapply(data, 1, fun)
. Możesz przekazać dodatkowe argumenty po argumencie FUN (jak już zasugerował Dirk):Następnie możesz zrobić coś takiego:
źródło
Oto krótki przykład zastosowania funkcji do każdego wiersza macierzy. (Tutaj zastosowana funkcja normalizuje każdy wiersz do 1.)
Uwaga: Wynik z operacji
apply()
musiał zostać przetransponowany za pomocą,t()
aby uzyskać ten sam układ co macierz wejściowaA
.Wynik:
źródło
Pierwszym krokiem byłoby utworzenie obiektu funkcji, a następnie zastosowanie go. Jeśli potrzebujesz obiektu macierzowego, który ma taką samą liczbę wierszy, możesz go wstępnie zdefiniować i użyć postaci obiektu [], jak pokazano na ilustracji (w przeciwnym razie zwrócona wartość zostanie uproszczona do wektora):
Jeśli chcesz użyć innych parametrów niż domyślne, wywołanie powinno zawierać nazwane argumenty po funkcji:
Apply () można również stosować w tablicach o wyższych wymiarach, a argument MARGIN może być wektorem, jak również pojedynczą liczbą całkowitą.
źródło
Aplikuj dobrze, ale działa dość wolno. Używanie sapply i vapply może być przydatne. Dplyr's rowwise również może być przydatny Zobaczmy przykład, jak zrobić iloczyn wierszowy dowolnej ramki danych.
Zauważ, że przypisanie do zmiennej przed użyciem vapply / sapply / apply jest dobrą praktyką, ponieważ bardzo skraca czas. Zobaczmy wyniki microbenchmark
Przyjrzyj się uważnie, w jaki sposób używana jest funkcja t ()
źródło
b <- t(iris[1:10, 1:3])
iapply(b, 2 prod)
.Innym podejściem, jeśli chcesz użyć różnych części zestawu danych zamiast pojedynczej wartości, jest użycie
rollapply(data, width, FUN, ...)
. Użycie wektora szerokości umożliwia zastosowanie funkcji w zmiennym oknie zbioru danych. Użyłem tego do zbudowania procedury filtrowania adaptacyjnego, chociaż nie jest ona zbyt wydajna.źródło