Jaka jest różnica między lapply a do.zadzwonić?
Ostatnio uczę się R i jestem zdezorientowany przez dwie funkcje: lapply
i do.call
. Wygląda na to, że są one po prostu podobne do funkcji map
w Lispie. Ale dlaczego istnieją dwie funkcje o tak innej nazwie? Dlaczego R nie używa funkcji o nazwie map
?
7 answers
Istnieje funkcja o nazwie Map
, która może być podobna do map w innych językach:
-
lapply
zwraca listę o tej samej długości co X, której każdy element jest wynikiem zastosowania FUN do odpowiadającego mu elementu X. do.call
konstruuje i wykonuje wywołanie funkcji z nazwy lub funkcji oraz listy argumentów, które mają być do niej przekazane.Map
stosuje funkcję do odpowiednich elementów danych wektorów...Map
jest prosty wrapper domapply
, który nie próbuje uprościć wyniku, podobny do mapcar Common Lispu (z argumentami jednak poddanymi recyklingowi). Przyszłe wersje mogą pozwolić na pewną kontrolę typu wyniku.
-
Map
jest owijką wokółmapply
-
lapply
jest szczególnym przypadkiemmapply
- dlatego
Map
ilapply
będą podobne w wielu przypadkach.
Na przykład, oto lapply
:
lapply(iris, class)
$Sepal.Length
[1] "numeric"
$Sepal.Width
[1] "numeric"
$Petal.Length
[1] "numeric"
$Petal.Width
[1] "numeric"
$Species
[1] "factor"
I to samo za pomocą Map
:
Map(class, iris)
$Sepal.Length
[1] "numeric"
$Sepal.Width
[1] "numeric"
$Petal.Length
[1] "numeric"
$Petal.Width
[1] "numeric"
$Species
[1] "factor"
do.call
przyjmuje funkcję jako wejście i przekazuje jej inne argumenty do funkcji. Jest szeroko stosowany, na przykład, do łączenia list w prostsze struktury (często z rbind
lub cbind
).
Na przykład:
x <- lapply(iris, class)
do.call(c, x)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
"numeric" "numeric" "numeric" "numeric" "factor"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-29 15:37:35
lapply
stosuje funkcję nad listą, do.call
wywołuje funkcję z listą argumentów. Dla mnie to wygląda na sporą różnicę...
Aby podać przykład z listą:
X <- list(1:3,4:6,7:9)
Z lapply otrzymujesz średnią każdego elementu na liście w następujący sposób:
> lapply(X,mean)
[[1]]
[1] 2
[[2]]
[1] 5
[[3]]
[1] 8
do.call
podaje błąd, ponieważ mean oczekuje, że argument "trim" będzie równy 1.
Z drugiej strony rbind
wiąże wszystkie argumenty w wierszu. Więc aby związać x wierszem, robisz :
> do.call(rbind,X)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
Jeśli użyłbyś lapply
, R zastosowałby rbind
do każdego elementu listy, dając Ci ten nonsens:
> lapply(X,rbind)
[[1]]
[,1] [,2] [,3]
[1,] 1 2 3
[[2]]
[,1] [,2] [,3]
[1,] 4 5 6
[[3]]
[,1] [,2] [,3]
[1,] 7 8 9
Aby mieć coś takiego jak mapa, potrzebujesz ?mapply
, co jest czymś zupełnie innym. Aby uzyskać np. średnią każdego elementu w X, ale z innym przycinaniem, można użyć :
> mapply(mean,X,trim=c(0,0.5,0.1))
[1] 2 5 8
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-29 15:11:51
lapply
jest podobny do map
, do.call
nie jest. lapply
stosuje funkcję do wszystkich elementów listy, do.call
wywołuje funkcję, w której wszystkie argumenty funkcji znajdują się na liście. Tak więc dla listy elementów n
lapply
ma wywołania funkcji n
, a do.call
ma tylko jedno wywołanie funkcji. Więc {[4] } jest zupełnie inna od lapply
. Mam nadzieję, że to wyjaśni twój problem.
Przykład kodu:
do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))
I:
lapply(c(1, 2, 4, 1, 2), function(x) x + 1)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-19 02:59:53
W najprostszych słowach:
lapply() stosuje daną funkcję dla każdego elementu na liście, więc będzie kilka wywołań funkcji.
zrób.call() stosuje daną funkcję do listy jako całości, więc jest tylko jedno wywołanie funkcji.
Najlepszym sposobem na naukę jest pobawienie się przykładami funkcji w dokumentacji R.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-24 16:19:01
Chociaż było wiele odpowiedzi, oto mój przykład odniesienia. Załóżmy, że mamy listę danych jako:
L=list(c(1,2,3), c(4,5,6))
Funkcja lapply zwraca listę.
lapply(L, sum)
Powyższe oznacza coś takiego jak poniżej.
list( sum( L[[1]]) , sum( L[[2]]))
[[5]}teraz zróbmy to samo dla zrobić.call
do.call(sum, L)
To znaczy
sum( L[[1]], L[[2]])
W naszym przykładzie zwraca 21. Krótko mówiąc, lapply zawsze zwraca listę, podczas gdy typ zwracania do.wywołanie zależy od wykonanej funkcji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-02 16:57:15
lapply()
jest funkcją podobną do mapy. do.call()
jest inny. Jest on używany do przekazywania argumentów do funkcji w formie listy zamiast ich wyliczania. Na przykład,
> do.call("+",list(4,5))
[1] 9
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-29 15:34:42
Różnica między nimi to:
lapply(1:n,function,parameters)
= > This send 1, parameters to function = > to wysyła 2, parametry do funkcji i tak dalej
do.call
Po prostu wysyła 1 ... n jako wektor i parametry do funkcji
Więc w apply masz n wywołań funkcji, w do.call you have just one
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-16 10:25:57