R语言do.call的简介及用法

1.介绍

do.call 函数用于构造和执行一个函数调用,可以通过指定函数名称或函数对象以及一个包含参数的列表来实现。以下是其主要参数和用法:

  • what: 要调用的函数,可以是一个函数对象或一个非空的字符字符串,表示函数的名称。
  • args: 一个包含函数调用参数的列表。args列表的names属性提供参数的名称。
  • quote: 一个逻辑值,指示是否引用参数。如果设置为FALSE(默认值),则参数在调用环境中进行评估,如果设置为TRUE,则对每个参数进行引用。
  • envir: 一个环境,在其中进行调用的评估。如果what是一个字符字符串并且参数是符号或引用表达式,这可能会很有用。

2.示例

以下是一些示例,演示如何使用do.call函数:

(1)示例1
do.call("complex", list(imaginary = 1:3))

这代码的含义是构造并执行一个调用 complex 函数的操作。

解释如下:

  1. complex 函数: complex 是一个内置的 R 函数,用于创建复数。复数由实部和虚部组成。在这个上下文中,complex 函数将一组虚部作为参数,返回相应虚部的复数。
  2. do.call 函数: do.call 函数用于将函数调用作为参数传递给另一个函数并执行。它的第一个参数是一个函数或函数名,第二个参数是一个参数列表。
  3. 参数列表: list(imaginary = 1:3) 是一个包含一个元素的列表,该元素是一个整数向量 1:3。在复数的上下文中,这将被解释为虚部的值。imaginary 是一个参数名,它指定了这个参数的名称。

因此,do.call("complex", list(imaginary = 1:3)) 的执行过程如下:

  • do.call 将调用 complex 函数,并将 list(imaginary = 1:3) 中的参数传递给 complex 函数。
  • complex 函数接收到这个参数,创建了包含虚部为 1、2 和 3 的复数。

这段代码的结果将是一个复数的向量,表示虚部分别为 1、2 和 3 的三个复数。

(2)示例2
tmp <- expand.grid(letters[1:2], 1:3, c("+", "-"))
do.call("paste", c(tmp, sep = ""))

这段代码的含义是使用 do.call 函数来调用 paste 函数,并将 tmp 数据框的列作为参数传递给 paste 函数。

让我们详细解释:

  1. expand.grid 函数: expand.grid 用于创建一个包含所有给定变量组合的数据框。在这里,letters[1:2] 生成字母 “a” 和 “b”,1:3 生成数字 1、2 和 3,c("+", "-") 生成字符向量 “+”, “-”。expand.grid 将这些变量的所有组合组成一个数据框 tmp
# 结果:
#   Var1 Var2 Var3
# 1    a    1    +
# 2    b    1    +
# 3    a    2    +
# 4    b    2    +
# 5    a    3    +
# 6    b    3    +
# 7    a    1    -
# 8    b    1    -
# 9    a    2    -
# 10   b    2    -
# 11   a    3    -
# 12   b    3    -
  1. do.call 函数: do.call 用于执行一个函数调用。第一个参数是要调用的函数(这里是 “paste”),第二个参数是传递给该函数的参数列表。

  2. 参数列表: c(tmp, sep = "")tmp 数据框的每一列作为参数传递给 paste 函数。 sep = "" 指定了 paste 函数的 sep 参数,表示在连接字符时不使用分隔符。

    所以,do.call("paste", c(tmp, sep = "")) 的执行过程如下:

    • do.call 调用 paste 函数,并将 tmp 数据框的每一列作为参数传递给 paste 函数。
    • paste 函数接收到这些参数,将每一行的值连接在一起,使用空字符串作为分隔符,形成一个字符向量。
    • 最终结果是一个包含连接后的字符串的字符向量:
[1] "a1+" "b1+" "a2+" "b2+" "a3+" "b3+" "a1-" "b1-" "a2-" "b2-" "a3-" "b3-"

这表示将 tmp 数据框的各列值按照指定规则连接在一起。

(3)示例3
do.call(paste, list(as.name("A"), as.name("B")), quote = TRUE)

这段代码的含义是使用 do.call 函数调用 paste 函数,将 as.name("A")as.name("B") 作为参数传递给 paste 函数,并在传递参数时对参数进行引用。

让我们详细解释:

  1. do.call 函数: do.call 用于执行一个函数调用。第一个参数是要调用的函数(这里是 paste),第二个参数是传递给该函数的参数列表。
  2. 参数列表: list(as.name("A"), as.name("B")) 创建一个包含两个元素的列表。每个元素都是 as.name 函数的调用,将字符 “A” 和 “B” 转换为符号。在这个上下文中,as.name 用于创建符号对象,使得参数传递时可以保持原始字符的引用。
  3. quote 参数: quote = TRUE 指定了在传递参数时对参数进行引用。这意味着 do.call 不会对参数进行求值,而是保持它们作为符号的形式。

因此,do.call(paste, list(as.name("A"), as.name("B")), quote = TRUE) 的执行过程如下:

  • do.call 调用 paste 函数,并将 list(as.name("A"), as.name("B")) 中的参数传递给 paste 函数。
  • paste 函数接收到这两个参数,由于 quote = TRUE,它会保持这两个参数的符号形式而不进行求值。
  • 最终结果是一个符号向量,表示传递给 paste 函数的两个参数的符号形式:
[1] A B

这个符号向量反映了 do.call 在传递参数时对参数进行了引用,而不是对其进行求值。

(4)示例4
A <- 2
f <- function(x) print(x^2)
env <- new.env()
assign("A", 10, envir = env)
assign("f", f, envir = env)
do.call("f", list(A), envir = env)        # 4

这段代码的含义是在指定环境中使用 do.call 函数调用一个函数。

让我们逐步解释:

  1. 定义全局变量 A 和函数 f
A <- 2
f <- function(x) print(x^2)

在全局环境中定义了一个变量 A,其值为2,以及一个函数 f,该函数接收一个参数 x,并打印 x^2

  1. 创建新的环境 env
env <- new.env()

使用 new.env() 函数创建了一个新的环境对象 env

  1. 在新环境中重新定义 Af
assign("A", 10, envir = env)
assign("f", f, envir = env)

使用 assign 函数在环境 env 中重新定义了变量 A 的值为10,并将函数 f 赋值给了环境 env 中的同名函数。

  1. 使用 do.call 调用函数 f
do.call("f", list(A), envir = env)
  1. do.call 调用了函数 f,并将参数列表 list(A) 传递给了 f 函数。此时,A 是环境 env 中的变量,其值为10。

    因此,f(10) 就相当于执行 print(10^2),结果为 100。所以,最后的输出是 100

总的来说,这段代码演示了如何在一个指定的环境中使用 do.call 来调用一个函数,并且该函数可以在指定环境中找到其定义的变量。

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mengke25

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值