簡體   English   中英

將字符串作為參數名稱/值對傳遞給R函數

[英]Passing a character string as a parameter name/value pair into a R function

我想使用一個或多個字符串,以將其作為參數的名稱/值對傳遞給函數。 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

我們可以創建環境並在環境中創建變量。 然后將環境轉換為list並將變量列表作為參數傳遞給函數。

要了解有關R環境的更多信息,請參考此鏈接

沒有字符串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 

上面的@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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM