簡體   English   中英

如何使用在函數主體中定義的變量作為該函數的參數?

[英]How can I use variables defined in the body of a function as argument to that function?

我正在研究這個問題:第一人稱擲出3個骰子中的1個,然后第二人擲出其余2個骰子中的1個。 骰子為6面,但每面都有隨機數(與每個骰子相對應的數字在該骰子的樣本中列出)。

approximated.probability.that.c1.wins <- function(n, k, c1, c2){

    red <- replicate(k, sum(sample(c(3,3,3,3,3,6), n)))
    yellow <- replicate(k, sum(sample(c(2,2,2,5,5,5), n)))     
    green <- replicate(k, sum(sample(c(1,4,4,4,4,4), n))) 

    return(sum(c1 > c2))
}

approximated.probability.that.c1.wins(1, 1000, red, green)

當我用sum(red > green)類的函數中的向量替換c1c2時,我的函數起作用。 但是,當我按原樣運行該函數時,它將返回錯誤"object 'red' not found" 目的是用調用函數時定義的任何顏色替換c1c2

您要執行的操作是相當高級的R。請注意, redgreen未在父框架中定義,因此在常規編程中這是行不通的。 但是,如果您將它們捕獲為表達式,然后在存在redgreenyellow求值,則它確實起作用。 這是一種實現方法:

library(rlang)
approximated.probability.that.c1.wins <- function(n, k, c1, c2){
  c1 <- enexpr(c1)
  c2 <- enexpr(c2)

  red <- replicate(k, sum(sample(c(3,3,3,3,3,6), n)))
  yellow <- replicate(k, sum(sample(c(2,2,2,5,5,5), n)))     
  green <- replicate(k, sum(sample(c(1,4,4,4,4,4), n))) 

  # note: added divide by k to calculate probability
  return(sum(eval(c1) > eval(c2))/k)
}

set.seed(1234)
approximated.probability.that.c1.wins(1, 1000, red, green)
[1] 0.299

我們可以通過將base R作為字符串傳遞,然后使用get來獲取值,從而對base R進行此操作

approximated.probability.that.c1.wins <- function(n, k, c1, c2){

   red <- replicate(k, sum(sample(c(3,3,3,3,3,6), n)))
   yellow <- replicate(k, sum(sample(c(2,2,2,5,5,5), n)))     
    green <- replicate(k, sum(sample(c(1,4,4,4,4,4), n))) 

   return(sum(get(c1) > get(c2)))
}

approximated.probability.that.c1.wins(1, 3, 'red', 'green')

非標准評估

創建一個由redyellowgreen三個部分組成的列表L 然后,可以使用指示的表達式將非標准輸入轉換為用於查找L中適當組件的字符串。

approximated.probability.that.c1.wins <- function(n, k, c1, c2){

    L <- list(red = replicate(k, sum(sample(c(3,3,3,3,3,6), n))),
              yellow = replicate(k, sum(sample(c(2,2,2,5,5,5), n))),
              green = replicate(k, sum(sample(c(1,4,4,4,4,4), n))))

    c1 <- deparse(substitute(c1))  ## 
    c2 <- deparse(substitute(c2))  ##

    sum(L[[c1]] > L[[c2]])
}

approximated.probability.that.c1.wins(1, 1000, red, green)

標准評價

要使用標准評估(而不是上面使用的非標准評估),我們將傳遞"red""green"而不是redgreen ,然后我們不再需要上面標有##的兩行,因此代碼簡化為:

approximated.probability.that.c1.wins <- function(n, k, c1, c2){

    L <- list(red = replicate(k, sum(sample(c(3,3,3,3,3,6), n))),
              yellow = replicate(k, sum(sample(c(2,2,2,5,5,5), n))),
              green = replicate(k, sum(sample(c(1,4,4,4,4,4), n))))

    sum(L[[c1]] > L[[c2]])
}

approximated.probability.that.c1.wins(1, 1000, "red", "green")

使用環境

盡管通常最好不要使用環境,定義L的替代方法是使用問題中的原始代碼,但將正文的最后一行替換為:

e <- environment()
sum(e[[c1]] > e[[c2]])

e包含當前函數中的所有變量。 這將適用於標准評估部分以及使用標記為##的行的非標准評估。

暫無
暫無

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

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