您可以在文本字符串中调用函数参数吗?

ano*_*ona 2 r

我是 R 新手,我只是想知道是否可以在文本字符串中调用函数变量,例如而不是这样:

welcome <- function(name,age,location) {paste("Welcome! Your name is", name,"you are",age,"years old and live in", location)}

welcome("Emma","26","UK")
Run Code Online (Sandbox Code Playgroud)

像这样的东西:

welcome <- function(name,age,location) {paste("Welcome! Your name is **name:** you are **age:** years old and live in **location:**")}

welcome(Emma,26,UK)
Run Code Online (Sandbox Code Playgroud)

Sam*_*amR 6

一般来说,在 R 中以这种方式编程并不符合习惯。也有例外 - 您可能希望阅读Advanced R 的非标准评估章节。

如果您确实需要这样做,有两种我熟悉的方法:deparse(substitute())match.call()

首先,deparse(substitute())

welcome2 <- function(name, age, location) {
    paste(
        "Welcome! Your name is",
        deparse(substitute(name)),
        "you are",
        age, # No need to deparse an integer
        "years old and live in",
        deparse(substitute(location))
    )
}

welcome2(Emma, 26, UK)
# [1] "Welcome! Your name is Emma you are 26 years old and live in UK"
Run Code Online (Sandbox Code Playgroud)

然而,这可能表现得 令人惊讶

或者,您可以使用match.call(),它更干净:

welcome3 <- function(name, age, location) {
    args <- as.list(match.call())
    paste(
        "Welcome! Your name is",
        args$name,
        "you are",
        args$age,
        "years old and live in",
        args$location
    )
}

welcome3(Emma, 26, UK)
# [1] "Welcome! Your name is Emma you are 26 years old and live in UK"
Run Code Online (Sandbox Code Playgroud)

不过,不这样做的一个原因是,如果从另一个函数调用,这些方法将不起作用。例如:

welcome_wrapper3  <- function(name, age, location) {
    welcome3(name, age, location)
}

welcome_wrapper3(Emma, 26, UK)
# [1] "Welcome! Your name is name you are age years old and live in location"
Run Code Online (Sandbox Code Playgroud)

使用这两种方法都会得到相同的结果。此外,如果您希望函数评估您的参数,则会导致问题。比较:

welcome("Emma", 26-1, "UK")
# [1] "Welcome! Your name is Emma you are 25 years old and live in UK"
welcome3(Emma, 26-1, UK)
# [1] "Welcome! Your name is Emma you are - years old and live in UK"  "Welcome! Your name is Emma you are 26 years old and live in UK"
# [3] "Welcome! Your name is Emma you are 1 years old and live in UK" 
Run Code Online (Sandbox Code Playgroud)

因此,除非有充分的理由,否则通常不应该这样做。

使用sprintf()

您还可以按照 Roland 的评论中的建议使用sprintf()代替paste(),这可以使代码更干净一些。您需要使用match.call()[-1]来删除第一个参数,即函数的名称,即welcome4在本例中。您还需要使用as.character()asas.list(match.call())返回符号列表,您不能直接将其提供给sprintf().

welcome4 <- function(name, age, location) {
    do.call(sprintf, c(
        "Welcome! Your name is %s you are %s years old and live in %s",
        lapply(as.list(match.call())[-1], as.character)
    ))
}

welcome4(Emma, 26, UK)
# [1] "Welcome! Your name is Emma you are 26 years old and live in UK"
Run Code Online (Sandbox Code Playgroud)