私は最近Rを学んでおり、2つの関数lapply
とdo.call
で混乱しています。これらは、LISPのmap
関数に似ているようです。しかし、なぜそのような異なる名前を持つ2つの関数があるのでしょうか? Rがmap
という関数を使用しないのはなぜですか?
Map
という関数があり、他の言語のmapに似ている場合があります。
lapply
は、Xと同じ長さのリストを返します。各要素は、Xの対応する要素にFUNを適用した結果です。
do.call
は、名前または関数と、それに渡される引数のリストから関数呼び出しを構築して実行します。
Map
は、指定されたベクトルの対応する要素に関数を適用します... Map
は、mapply
の単純なラッパーであり、Common LISPのmapcar(ただし、引数はリサイクルされます)と同様、結果を単純化しようとしません。将来のバージョンでは、結果タイプをある程度制御できるようになる可能性があります。
Map
はmapply
のラッパーですlapply
は、mapply
の特殊なケースですMap
とlapply
は多くの場合類似しています。たとえば、次はlapply
です。
lapply(iris, class)
$Sepal.Length
[1] "numeric"
$Sepal.Width
[1] "numeric"
$Petal.Length
[1] "numeric"
$Petal.Width
[1] "numeric"
$Species
[1] "factor"
そして、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
は関数を入力として受け取り、その関数への他の引数を飛び散らせます。たとえば、リストをより単純な構造(多くの場合、rbind
またはcbind
を使用)にアセンブルするために広く使用されます。
例えば:
x <- lapply(iris, class)
do.call(c, x)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
"numeric" "numeric" "numeric" "numeric" "factor"
lapply
はリストに関数を適用し、do.call
は引数のリストを使用して関数を呼び出します。それは私にはかなり違いのように見えます...
リストを使用して例を与えるには:
X <- list(1:3,4:6,7:9)
Lapplyを使用すると、次のようにリスト内のすべての要素の平均を取得できます。
> lapply(X,mean)
[[1]]
[1] 2
[[2]]
[1] 5
[[3]]
[1] 8
do.call
は、引数 "trim"が1であることを期待しているため、エラーを返します。
一方、rbind
はすべての引数を行ごとにバインドします。 Xを行ごとにバインドするには、次のようにします。
> do.call(rbind,X)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
lapply
を使用する場合、Rはリストのすべての要素にrbind
を適用し、このナンセンスを与えます。
> 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
Mapのようなものを使用するには、?mapply
が必要です。たとえば、Xのすべての要素の平均を取得するために、異なるトリミングを使用するには、次を使用できます。
> mapply(mean,X,trim=c(0,0.5,0.1))
[1] 2 5 8
lapply
はmap
に似ていますが、do.call
は似ていません。 lapply
はリストのすべての要素に関数を適用し、do.call
はすべての関数引数がリストにある関数を呼び出します。したがって、n
要素リストの場合、lapply
にはn
関数呼び出しがあり、do.call
には1つの関数呼び出ししかありません。したがって、do.call
はlapply
とはまったく異なります。これで問題が明らかになることを願っています。
コード例:
do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))
そして:
lapply(c(1, 2, 4, 1, 2), function(x) x + 1)
最も簡単な言葉で:
lapply()はリスト内の各要素に特定の関数を適用するため、いくつかの関数呼び出しがあります。
do.call()リスト全体に特定の関数を適用するため、関数呼び出しは1つだけです。
学ぶための最良の方法は、Rのドキュメントにある関数の例をいじることです。
lapply()
は、マップのような関数です。 do.call()
は異なります。引数を列挙する代わりに、リスト形式で関数に渡すために使用されます。例えば、
> do.call("+",list(4,5))
[1] 9
多くの回答がありましたが、参考のために私の例を示します。次のようなデータのリストがあるとします:
L=list(c(1,2,3), c(4,5,6))
関数lapplyはリストを返します。
lapply(L, sum)
上記は以下のようなものを意味します。
list( sum( L[[1]]) , sum( L[[2]]))
ここで、do.callに対して同じことをしましょう。
do.call(sum, L)
その意味は
sum( L[[1]], L[[2]])
この例では、21を返します。要するに、lapplyは常にリストを返しますが、do.callの戻り値の型は実際に実行される関数に依存します。
両方の違いは次のとおりです。
lapply(1:n,function,parameters)
=>これは1、パラメーターを関数に送信=>これは2、パラメーターを関数に送信、など
do.call
関数として1 ... nをベクトルとパラメーターとして送信するだけです
したがって、適用ではn個の関数呼び出しがあり、do.callでは1つだけです