我申请和你申请有什么区别?

我最近在学 R,但是被两个函数搞糊涂了: lapplydo.call。它们似乎与 Lisp 中的 map函数相似。但是为什么会有两个名字如此不同的函数呢?为什么 R 不用一个叫 map的函数呢?

85090 次浏览

lapply类似于 map,而 do.call不类似。lapply对列表中的所有元素应用函数,do.call调用所有函数参数都在列表中的函数。因此,对于 n元素列表,lapplyn函数调用,而 do.call只有一个函数调用。所以 do.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)

有一个名为 Map的函数可能类似于其他语言中的 map:

  • lapply返回一个与 X 长度相同的列表,其中每个元素都是对 X 的相应元素应用 FUN 的结果。

  • do.call构造并执行来自名称或函数的函数调用以及要传递给它的参数列表。

  • Map对给定向量的相应元素应用一个函数... ... Mapmapply的一个简单包装器,它并不试图简化结果,类似于 Common Lisp 的 mapcar (但是参数被回收)。未来的版本可能允许对结果类型进行一些控制。


  1. Map是围绕 mapply的包装器
  2. lapplymapply的一个特例
  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接受一个函数作为输入,并将它的其他参数传递给该函数。它被广泛使用,例如,将列表组装成更简单的结构(通常使用 rbindcbind)。

例如:

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)

使用 lapplication,你可以得到列表中每个元素的平均值,如下所示:

> lapply(X,mean)
[[1]]
[1] 2


[[2]]
[1] 5


[[3]]
[1] 8

do.call给出了一个错误,因为 mean 期望参数“ trim”为1。

另一方面,rbind按行绑定所有参数:

> 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()不一样。它用于以列表形式将参数传递给函数,而不是枚举它们。比如说,

> do.call("+",list(4,5))
[1] 9

用最简单的话说:

  1. lapply()为列表中的每个元素应用给定的函数,因此将有多个函数调用。

  2. do.call()将给定的函数作为一个整体应用于列表,因此只有一个函数调用。

学习的最佳方法是使用 R 文档中的函数示例。

两者的区别是:

lapply(1:n,function,parameters)

= > 这个 send 1,函数的参数 = > this 将参数发送到函数 诸如此类

do.call

只是将1... n 作为向量和参数发送给函数

所以在应用程序中有 n 个函数调用,在 do.call 中只有一个

虽然已经有很多答案,这里是我的例子作为参考。 假设我们有一个数据列表:

L=list(c(1,2,3), c(4,5,6))

函数 lapplication 返回一个列表。

lapply(L, sum)

上面的意思和下面差不多。

list( sum( L[[1]]) , sum( L[[2]]))

现在让我们为 do.call 做同样的事情

do.call(sum, L)

意思是

sum( L[[1]], L[[2]])

在我们的示例中,它返回21。简而言之,lapplication 总是返回一个列表,而 do.call 的返回类型实际上取决于所执行的函数。