173

私は最近Rを学んでいて、2つの関数で混乱しています:lapplydo.callmapそれらはLispの機能にちょうど似ているようです。しかし、なぜそのような異なる名前の2つの関数があるのでしょうか。なぜRは単にという関数を使わないのmapですか?

4

7 に答える 7

145

Map他の言語のマップに似ている可能性のあると呼ばれる関数があります。

  • lapplyXと同じ長さのリストを返します。各要素は、Xの対応する要素にFUNを適用した結果です。

  • do.call名前または関数からの関数呼び出しと、それに渡される引数のリストを作成して実行します。

  • Map与えられたベクトルの対応する要素に関数を適用します...は、 Common Lispのマップカーと同様に、結果を単純化しようとしないMap単純なラッパーです(ただし、引数はリサイクルされます)。mapply将来のバージョンでは、結果タイプをある程度制御できるようになる可能性があります。


  1. Mapラッパーですmapply
  2. lapplyの特殊なケースですmapply
  3. したがってMaplapply多くの場合、同様になります。

たとえば、ここにあります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" 
于 2012-05-29T15:11:00.050 に答える
69

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
于 2012-05-29T15:11:51.637 に答える
45

lapplyに似ていますがmap、そうでdo.callはありません。lapplyリストのすべての要素に関数を適用し、do.callすべての関数の引数がリストにある関数を呼び出します。したがって、n要素リストの場合、関数呼び出しがあり、関数呼び出しはlapply1つだけです。したがって、とはかなり異なります。これで問題が明らかになることを願っています。ndo.calldo.calllapply

コード例:

do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))

と:

lapply(c(1, 2, 4, 1, 2), function(x) x + 1)
于 2012-05-29T15:08:58.200 に答える
32

最も簡単な言葉で:

  1. lapply()は、リスト内の各要素に特定の関数を適用するため、いくつかの関数呼び出しがあります。

  2. do.call()は、指定された関数をリスト全体に適用するため、関数呼び出しは1つだけです。

学ぶための最良の方法は、Rドキュメントの関数例を試してみることです。

于 2013-10-29T11:48:39.930 に答える
18

多くの回答がありますが、参考のためにここに私の例を示します。次のようなデータのリストがあるとします。

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の戻りタイプは実際には実行された関数に依存します。

于 2015-06-02T16:52:10.760 に答える
14

lapply()マップのような関数です。do.call()異なります。引数を列挙する代わりに、リスト形式で関数に引数を渡すために使用されます。例えば、

> do.call("+",list(4,5))
[1] 9
于 2012-05-29T15:12:10.410 に答える
7

両方の違いは次のとおりです。

lapply(1:n,function,parameters)

=>これは関数に1つのパラメータを送信します=>これは関数に2つのパラメータを送信します

do.call 

関数へのベクトルとパラメータとして1…nを送信するだけです

したがって、applyではn個の関数呼び出しがあり、do.callでは1つだけです。

于 2014-08-16T10:15:46.167 に答える