私は最近Rを学んでいて、2つの関数で混乱しています:lapply
とdo.call
。map
それらはLispの機能にちょうど似ているようです。しかし、なぜそのような異なる名前の2つの関数があるのでしょうか。なぜRは単にという関数を使わないのmap
ですか?
7 に答える
Map
他の言語のマップに似ている可能性のあると呼ばれる関数があります。
lapply
Xと同じ長さのリストを返します。各要素は、Xの対応する要素にFUNを適用した結果です。do.call
名前または関数からの関数呼び出しと、それに渡される引数のリストを作成して実行します。Map
与えられたベクトルの対応する要素に関数を適用します...は、 Common Lispのマップカーと同様に、結果を単純化しようとしないMap
単純なラッパーです(ただし、引数はリサイクルされます)。mapply
将来のバージョンでは、結果タイプをある程度制御できるようになる可能性があります。
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
1つだけです。したがって、とはかなり異なります。これで問題が明らかになることを願っています。n
do.call
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ドキュメントの関数例を試してみることです。
多くの回答がありますが、参考のためにここに私の例を示します。次のようなデータのリストがあるとします。
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()
マップのような関数です。do.call()
異なります。引数を列挙する代わりに、リスト形式で関数に引数を渡すために使用されます。例えば、
> do.call("+",list(4,5))
[1] 9
両方の違いは次のとおりです。
lapply(1:n,function,parameters)
=>これは関数に1つのパラメータを送信します=>これは関数に2つのパラメータを送信します
do.call
関数へのベクトルとパラメータとして1…nを送信するだけです
したがって、applyではn個の関数呼び出しがあり、do.callでは1つだけです。