我想使用一个字符串,以便将它作为参数的名称/值对传递给函数。 Test1显示了我想要实现的目标。在Test2中,R不调用getInfo(PHONE_NUMBER = 123456),但是,根据参数顺序,使用getInfo(FULL_NAME =“PHONE_NUMBER = 123456”)。我怎么能改变它?
该字符串还可能包含我想要解析的各种参数,例如“PHONE_NUMBER = 123456,ZIP = 1234”
s <- "PHONE_NUMBER = 123456"
getInfo <- function(FULL_NAME = "", FIRST_NAME = "", LAST_NAME = "",
ZIP = "", PHONE_NUMBER = "") {
l <- as.list(match.call())
myNames <- names(unlist(l[c(2, length(l))]))
print(myNames)
myValues <- unlist(l[c(2, length(l))])
print(myValues)
searchString <- paste(myNames, myValues, sep = "=", collapse = "&")
searchString <- paste0("search?PHONE_NUMBER=", searchString)
}
# Test 1: Setting the paramter manually
getInfo(PHONE_NUMBER = 123456)
#> [1] "PHONE_NUMBER" "PHONE_NUMBER"
#> PHONE_NUMBER PHONE_NUMBER
#> 123456 123456
# Test2 : Attempt to pass string as name/value fails; R uses the complete string as the first paramter (FULL_NAME = "PHONE_NUMBER = 123456") instead
getInfo(s)
#> [1] "FULL_NAME" "FULL_NAME"
#> $FULL_NAME
#> s
#>
#> $FULL_NAME
#> s
答案 0 :(得分:1)
我们可以创建一个环境并在环境中创建变量。然后将环境转换为列表,并将变量列表作为参数传递给函数。
要了解有关R中环境的更多信息,请参阅此link。
没有字符串s
getInfo(PHONE_NUMBER = 123456)
do.call("getInfo", list(PHONE_NUMBER = 123456))
# [1] "PHONE_NUMBER" "PHONE_NUMBER"
# PHONE_NUMBER PHONE_NUMBER
# 123456 123456
字符串s
包含单个参数
s <- "PHONE_NUMBER = 123456"
myenv <- new.env() # create new environment
eval(parse(text = s), envir = myenv) # create variables inside environment using string s
ls(name = myenv) # list all variables inside the environment
# [1] "PHONE_NUMBER"
myenv$PHONE_NUMBER
# [1] 123456
do.call("getInfo", as.list.environment(myenv)) # call the function by passing the arguments which is obtained by converting environment into list
# [1] "PHONE_NUMBER" "PHONE_NUMBER"
# PHONE_NUMBER PHONE_NUMBER
# 123456 123456
字符串s
包含多个参数 - 适用于单个或多个参数
s <- "PHONE_NUMBER = 123456, ZIP = 1234"
s <- unlist(strsplit(s, split = ",", fixed = TRUE)) # split string s using comma separator
s
# [1] "PHONE_NUMBER = 123456" " ZIP = 1234"
myenv <- new.env()
eval(parse(text = s), envir = myenv)
ls(name = myenv)
# [1] "PHONE_NUMBER" "ZIP"
do.call("getInfo", as.list.environment(myenv))
# [1] "ZIP" "PHONE_NUMBER"
# ZIP PHONE_NUMBER
# 1234 123456
答案 1 :(得分:0)
@Sathish回答很好,但不适用于更复杂的参数。 例如,当要传递矢量(包含逗号)时:
> s <- "PHONE_NUMBER = 123456, ZIP = c(1234, 4321)"
> s <- unlist(strsplit(s, split = ",", fixed = TRUE))
> myenv <- new.env()
> eval(parse(text = s), envir = myenv)
Error in parse(text = s) : <text>:3:2: unexpected numeric constant
2: ZIP = c(1234
3: 4321
有一种更好,更灵活的方法,使用R的机器来达到目的:
> s <- "PHONE_NUMBER = 123456, ZIP = c(1234, 4321)"
> getArgs <- function(...) return(list(...))
> pars <- try(eval(parse(text=sprintf("getArgs(%s)", s))), silent=TRUE)
> pars
$PHONE_NUMBER
[1] 123456
$ZIP
[1] 1234 4321
即使s
在语法上不正确,它也可以工作-在这种情况下,pars
将包含类"try-error"
的对象。
尽管如此,使用eval()
仍存在重要的安全风险。为了避免不愉快的意外(=用户执行任意代码),您可能希望禁止并删除任何“;”或s
中的换行符:
s <- gsub(";|\n", "", s)